[백준] 1022 소용돌이 예쁘게 출력하기 (C++)

Yookyubin·2023년 8월 12일
0

백준

목록 보기
44/68

문제

1022번: 소용돌이 예쁘게 출력하기

풀이

범위에 맞는 소용돌이를 구하고 숫자의 자릿수를 고려하여 공백을 삽입 후 출력하는 문제이다.

출력할 숫자를 담을 (r2 - r1 +1 ) * (c2 - c1 + 1) 크기의 2차원 배열을 만들고 소용돌이를 1부터 하나씩 숫자를 키워가며 해당 위치가 배열에 담길 위치인지 확인하며 배열에 담았다.
소용돌이를 탐색하기 위한 규칙으로는 우, 상, 좌, 하 방향으로 1->2, 2->3, 3->5, 5->7, 7->10, 10->13... 방향을 꺽고 직진할 칸 수를 늘려가는 규칙을 사용했다. (우,상), (좌,하)로 이동한 후 직진해야 할 칸 수가 늘어난다. 1, 1, 2, 2, 3, 3, 4, 4, ... 으로 직진할 칸수가 정해진다.

배열에 필요한 숫자를 모두 저장했는지 확인하기 위해 배열에 숫자를 저장할 때마다 개수를 세어 배열의 크기와 비교하였다.

숫자를 예쁘게 출력하기 위해 배열의 수들 중 자릿수가 가장 큰 수를 찾아야 하는데 이는 어짜피 가장 큰 수 이므로 이또한 배열에 수를 저장할 때 판단하여 따로 저장해두었다.
가장 큰 수의 자릿수를 계산하기 위해 수를 문자열로 바꾼 후 문자열의 길이를 측정하였고
각 행마다 새로운 문자열을 만들어 각 수의 자릿수와 가장 큰 수의 문자열과 비교하여 필요한 공백을 추가했다.
만든 문자열을 하나씩 출력하며 소용돌이를 예쁘게 출력할 수 있다.

코드

#include <iostream>
#include <string>
#include <vector>

using namespace std;

int r1, c1, r2, c2;
int maxVal = 0;
vector<vector<int>> nums;

int max(int a, int b) { return a > b ? a : b; }

void makeSpiral(){
    int x = 0;
    int y = 0;
    vector<int> dx = {0, -1, 0, 1};
    vector<int> dy = {1, 0, -1, 0};

    int val = 1;
    int cnt = 1;
    int dist = 1;
    if (r1 <= x && x <= r2 && c1 <= y && y <= c2){
        nums[x-r1][y-c1] = val; // nums[][] = 1;
        ++cnt;
    }
    int maxCnt = (r2 - r1 +1 ) * (c2 - c1 + 1);
    while (cnt <= maxCnt){
        for (int i=0; i<4; i++){
            if (i == 2)  dist++;
            for (int d=0; d<dist; d++){
                x += dx[i];
                y += dy[i];
                ++val;
                if (r1 <= x && x <= r2 && c1 <= y && y <= c2){
                    nums[x-r1][y-c1] = val;
                    maxVal = max(val, maxVal);
                    cnt++;
                }
            }
        }
        dist++;
    }
}

int main() {
    cin >> r1 >> c1 >> r2 >> c2;
    nums.assign(r2 - r1 + 1, vector<int>(c2 - c1 + 1, 0));

    makeSpiral();

    int maxLen = to_string(maxVal).length();
    vector<string> answer;
    for (int i=0; i<r2-r1+1; i++){
        string line="";
        for (int j=0; j<c2-c1+1; j++){
            string temp = to_string(nums[i][j]);
            for (int blank=0; blank < maxLen - temp.length(); blank++){
                line += " ";
            }
            line += temp + " ";
        }
        answer.push_back(line);
    }

    for (auto ans : answer){
        cout << ans << "\n";
    }
    return 0;
}
profile
붉은다리 제프

1개의 댓글

comment-user-thumbnail
2023년 8월 12일

큰 도움이 되었습니다, 감사합니다.

답글 달기