본문 바로가기

알고리즘 문제풀이/추천 문제

[ 백준 2290 ] LCD Test (C++)

반응형

https://www.acmicpc.net/problem/2290

 

2290번: LCD Test

첫째 줄에 두 개의 정수 s와 n이 들어온다. (1 ≤ s ≤ 10, 0 ≤ n ≤ 9,999,999,999)이다. n은 LCD 모니터에 나타내야 할 수 이며, s는 크기이다.

www.acmicpc.net

 

단순 구현 문제. 한 번쯤 풀어보면 나중에 비슷한 문제를 만났을 때 훨씬 수월하게 풀 수 있는 유형의 문제라고 생각한다.

 

우선 0 ~ 9 까지 lcd 판에 그리는 규칙부터 정의하자. 나는 아래와 같이 정의했다.

 

0 ~ 9 까지 각 숫자마다 출력해줘야 하는 번호를 배열로 나타내면 아래와 같다. 

 

int rules[10][7] = {
    {1,1,1,1,1,1,0}, // 0
    {0,1,1,0,0,0,0}, // 1
    {1,1,0,1,1,0,1}, // 2
    {1,1,1,1,0,0,1}, // 3
    {0,1,1,0,0,1,1}, // 4
    {1,0,1,1,0,1,1}, // 5
    {1,0,1,1,1,1,1}, // 6
    {1,1,1,0,0,0,0}, // 7
    {1,1,1,1,1,1,1}, // 8
    {1,1,1,1,0,1,1}  // 9
};

 

rules 이라는 이중 배열의 행은 출력하는 숫자가 되고, 각 행의 원소들은 위 그림에서 출력해야 하는 부분들을 나타낸다. 이를 토대로 그대로 출력만 해주면 끝이다.

 

출력을 해줄때 고려해줘야 하는 부분은 lcd 전광판의 배열 크기다. 우선 행의 크기는 똑같다. 문제에서 그렇게 가정했기 때문이다. 열의 크기는 s와 출력하는 숫자의 개수에 따라 달라지는데, 우선 답부터 먼저 보자. 

 

int row = 2 * s + 3;
int col = n.size() * (2 + s) + n.size() - 1;

 

행의 크기는 직접 해보면 어렵지 않게 이해할 수 있을 것이다. 0을 예로 들면 세로의 길이는 s가 두 번, 공백이 세 개 있다. 그렇다면 가로의 길이는? 먼저 모든 숫자는 (2 + s) 의 가로 길이를 가진다. 0을 예로 들면 s가 한 번, 공백이 두 개 있다. 따라서 (2 + s)를 출력해야하는 숫자 개수만큼 곱해준다. 뒤에 더해지는 값은 숫자마다의 공백을 의미한다. 문제에서 모든 숫자는 한 칸씩 띄워져 있다고 했다. 1을 빼주는 이유는 마지막 숫자는 공백이 필요 없기 때문이다.

 

다음으로 고려해줘야 할 부분은 기준점이다. 행은 크기가 고정이기 때문에 기준점이 필요 없지만, 열은 숫자를 계속 출력할수록 기준점이 바뀌기 때문에 기준점을 따로 설정해줘야 한다. 나는 기준점을 pos로 정의했다. 여기서 기준점은 숫자의 가장 좌측위를 말한다. 즉, 왼쪽 위 모퉁이!! 이제 기준점을 기준으로 모든 숫자를 출력해주기만 하면 끝!! 기준점을 기준으로 어떻게 출력하는지만 살펴보자..

 

void write(char **lcd, int Num, int s, int pos){
    for(int i = 0; i < 7; i++){
        if(rules[Num][i] == 1){ // 값이 1인 인덱스만 화면에 표시
            if(i == 0) for(int j = pos + 1; j <= pos + s; j++) lcd[0][j] = '-';
            else if(i == 1) for(int i = 1; i <= s; i++) lcd[i][pos + s + 1] = '|';
            else if(i == 2) for(int i = s + 2; i <= 2 * s + 1; i++) lcd[i][pos + s + 1] = '|';
            else if(i == 3) for(int j = pos + 1; j <= pos + s; j++) lcd[2 * s + 2][j] = '-';
            else if(i == 4) for(int i = s + 2; i <= 2 * s + 1; i++) lcd[i][pos] = '|';
            else if(i == 5) for(int i = 1; i <= s; i++) lcd[i][pos] = '|';
            else if(i == 6) for(int j = pos + 1; j <= pos + s; j++) lcd[s + 1][j] = '-';
        }
    }
}

 

Num은 출력하는 숫자를 말한다. 출력하고자 하는 숫자의 출력 규칙은 rules[Num]에 저장되어 있고, s와 pos를 통해 lcd 전광판에 숫자를 적어주면 된다. if문 안에 for문들은 직접 손으로 해보니깐 저렇게 돼서 그대로 적었다...

 

 

#include <iostream>
#include <string>
using namespace std;

int rules[10][7] = {
    {1,1,1,1,1,1,0},
    {0,1,1,0,0,0,0},
    {1,1,0,1,1,0,1},
    {1,1,1,1,0,0,1},
    {0,1,1,0,0,1,1},
    {1,0,1,1,0,1,1},
    {1,0,1,1,1,1,1},
    {1,1,1,0,0,0,0},
    {1,1,1,1,1,1,1},
    {1,1,1,1,0,1,1}
};

void print(char **lcd, int row, int col){
    for(int i = 0; i < row; i++){
        for(int j = 0; j < col; j++)
            cout << lcd[i][j];
        cout << endl;
    }
}

void write(char **lcd, int Num, int s, int pos){
    for(int i = 0; i < 7; i++){
        if(rules[Num][i] == 1){ // 값이 1인 인덱스만 화면에 표시
            if(i == 0) for(int j = pos + 1; j <= pos + s; j++) lcd[0][j] = '-';
            else if(i == 1) for(int i = 1; i <= s; i++) lcd[i][pos + s + 1] = '|';
            else if(i == 2) for(int i = s + 2; i <= 2 * s + 1; i++) lcd[i][pos + s + 1] = '|';
            else if(i == 3) for(int j = pos + 1; j <= pos + s; j++) lcd[2 * s + 2][j] = '-';
            else if(i == 4) for(int i = s + 2; i <= 2 * s + 1; i++) lcd[i][pos] = '|';
            else if(i == 5) for(int i = 1; i <= s; i++) lcd[i][pos] = '|';
            else if(i == 6) for(int j = pos + 1; j <= pos + s; j++) lcd[s + 1][j] = '-';
        }
    }
}

int main(){
    int s;
    string n;
    cin >> s >> n;
    
    int row = 2 * s + 3;
    int col = n.size() * (2 + s) + n.size() - 1;
    int pos = (s + 3) * -1;
    
    // 동적 할당
    char **lcd = new char*[row];
    for(int i = 0; i < row; i++)
        lcd[i] = new char[col];
    
    // 공백 초기화
    for(int i = 0; i < row; i++)
        for(int j = 0; j < col; j++)
            lcd[i][j] = ' ';
    
    for(int i = 0; i < n.size(); i++){
        pos += (s + 3); // 열의 기준점
        write(lcd, n[i] - 48, s, pos);
        // 아스키 코드 사용. 'n' - 48 = 정수형 n이 된다
    }
    
    print(lcd, row, col);
    
    for(int i = 0; i < row; i++)
        delete[] lcd[i];
    delete[] lcd;
    
    return 0;
}
반응형

'알고리즘 문제풀이 > 추천 문제' 카테고리의 다른 글

[ 백준 8911 ] 거북이 (C++)  (0) 2022.03.20
[ 백준 16113 ] 시그널 (C++)  (0) 2022.03.08
[ 백준 16506 ] CPU (C++)  (0) 2022.02.23
[ 백준 3568 ] iSharp (C++)  (0) 2022.02.21
[ 백준 5557 ] 1학년 (C++)  (0) 2022.02.14