졸려서 잠시 짬 내서 간단히 풀어본 문제입니다.
https://www.codewars.com/kata/536a155256eb459b8700077e/
길이가 N인 정방 행렬 구조에서 시계 방향으로 진행하며 count를 하는 문제입니다. 비슷한 문제를 있었던 거 같기도 하네요.
Your objective is to complete a function createSpiral(N) that receives an integer N and returns an NxN two-dimensional array with numbers 1 through NxN represented as a clockwise spiral.
Return an empty array if N < 1 or N is not int / number
Examples:
N = 3 Output: [[1,2,3],[8,9,4],[7,6,5]]
1 2 3
8 9 4
7 6 5
풀이는 다음과 같습니다.
먼저, std::vector<int> flat
을 정의해서 이동하는 위치에 count된 숫자를 저장하도록 했습니다.
그리고 std::vector<bool> visit
를 이용해서 한번 지나간 위치는 마킹해서 다시 지나가지 않도록 했습니다.
마지막으로 std::vector<std::pair<int, int>> dir
을 정의해서 4개 진행 방향을 정의한 다음에 진행이 불가능한 상황이 되면, 다음 진행 방향으로 변경해서 위치를 갱신하도록 했습니다.
std::vector<std::vector<int>> create_spiral(int n)
{
std::vector<std::vector<int>> ret;
if (n < 1)
return ret;
std::vector<int> flat(n * n, 0);
std::vector<bool> visit(n * n, false);
std::vector<std::pair<int, int>> dir = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
int dirD = 4;
int dirC = 0;
int x = 0, y = 0;
for (int i = 0; i < n * n; ++i)
{
int idx = y * n + x;
flat[idx] = i + 1;
visit[idx] = true;
std::pair<int, int> next = dir[dirC % dirD];
int nx = x + next.first;
int ny = y + next.second;
int nIdx = ny * n + nx;
if (nx < 0 || nx > n - 1 || ny < 0 || ny > n - 1 || nIdx < 0 || nIdx > n * n - 1 || visit[nIdx])
{
dirC++;
nx = x + dir[dirC % dirD].first;
ny = y + dir[dirC % dirD].second;
}
x = nx;
y = ny;
}
for (int i = 0; i < n; ++i)
{
std::vector<int> row(flat.begin() + i * n, flat.begin() + (i + 1) * n);
ret.push_back(row);
}
return ret;
}