다시 하락한 내 점수...😭
완전 탐색 파트가 끝나야 점수가 팍 오를 것 같다...!
열심히 해보쟈!!
n * m크기의 직사각형에 대문자 알파벳을 A부터 Z까지 순서대로 증가시키며 달팽이 모양으로 채우는 코드를 작성해보세요.
달팽이 모양이란 왼쪽 위 모서리에서 시작해서, 오른쪽, 아래쪽, 왼쪽, 위쪽 순서로 더 이상 채울 곳이 없을 때까지 회전하는 모양을 의미합니다.
Z 이후에는 다시 A부터 채우기 시작합니다.
n : 행(row), m : 열(column)을 의미합니다.
달팽이 모양으로 돌면서 숫자나 문자를 채우는 것은 달팽이 모양의 움직임만 잘 안다면 어렵지 않은 문제이다. 달팽이 모양을 90도 방향으로 회전하는 것는 것이라고 보면 다음과 같은 그림으로 설명이 된다.
dx, dy 배열을 다음과 같이 둔다면
//동 남 서 북
int dx[4] = {0, 1, 0, -1};
int dy[4] = {1, 0, -1, 0};
dir = 0 일 때 x = 0, y = 1
dir = 1 일 때 x = 1, y = 0
dir = 2 일 때 x = 0, y = -1
dir = 3 일 때 x = -1, y = 0 이다.
회전하고 싶을 때는 dir = (dir + 1) % 4라고 하면 된다. 그러면 3 -> 0이 될 수 있다!
dx, dy문제를 풀던 어느 날 갑자기 dx, dy를 수학의 x, y 좌표와 헷갈려서
동 남 서 북의 방향을
dx = {1, 0, -1, 0}, dy = {0, -1, 0, 1}으로 코드를 짰던 적이 있다...
아무리 풀어도 안되길래 곰곰이 보니 dx, dy가 아예 잘못 썼던 것...!
(코드트리에서도 x, y을 행, 열로 생각해야 한다고 나와있었다!!)
이 방향만 잘 설정해주고 문제를 접근하면 어렵지 않다.
해설에서는 A~Z 문자를 (char)(i % 26 + 'A')로 썼지만
나는 문자를 ++해주고 Z가 넘어가면 다시 A로 바꿔주는 형태로 만들었다.
#include <iostream>
#define MAX 100
using namespace std;
int n, m, x, y;
int dx[4] = {0, 1, 0, -1};
int dy[4] = {1, 0, -1, 0};
char arr[MAX][MAX] = {0};
bool InRange(int x, int y){
return 0 <= x && x < n && 0 <= y && y < m;
}
int main() {
cin >> n >> m;
arr[x][y] = 'A';
char alphabet = 'B';
int dir = 0;
for(int i = 1; i < n * m; i++){
int nx = x + dx[dir];
int ny = y + dy[dir];
if(!InRange(nx, ny) || arr[nx][ny] != 0){
dir = (dir + 1) % 4;
}
x += dx[dir];
y += dy[dir];
arr[x][y] = alphabet++;
if(alphabet > 'Z'){
alphabet = 'A';
}
}
for(int i=0; i<n; i++){
for(int j=0; j<m; j++){
cout << arr[i][j] << " ";
}
cout << endl;
}
return 0;
}