1) 겉에 거를 먼저 처리하고, 안으로 들어가는 방식을 생각함.
2) 상단부에서 배열이 이동하는 것과 우측에서 배열이 이동하는 시퀀스,
좌측에서 배열이 움직이는 시퀀스, 아래에서 배열이 이동하는 시퀀스가 다르다.
-> 분류해서 처리해야 겠다는 생각을 함.
3) 내부로 들어가는 코드를 어떻게 작성할까?? 생각해보니,,
사용되는 변수들을 이리 저리 볶아서 사용해야 겠다는 생각을 하게 되었다...
4) 그럼 while문을 언제 끝낼까? 생각했는데. n과 m 중에서 가장 작은거를 기준으로 해서 몇번 순회할지가 결정된다.
// 생각해보자.
// 세로 8칸 , 가로 4칸이라고 한다면
-> 세로가 넓지만, 가로가 4칸밖에 안되니까. 순회는 2번이다.
// 세로 10칸, 가로 4칸이면?
-> 이래도 가로가 순회는 2번이다.
#include <vector>
#include <iostream>
using namespace std;
int main()
{
int n, m, r;
cin >> n >> m >> r;
vector<vector<int>> v(n, vector<int>(m));
// 규칙성을 만들자.
for (int i = 0; i < n; ++i)
{
for (int j = 0; j < m; ++j)
{
cin >> v[i][j];
}
}
// 0) 바깥에서 안쪽으로 진행된다.
// 2) 상하좌우에 따라 구분해서 진행해야 한다.
vector<vector<int>> v2(n, vector<int>(m));
// 바깥쪽 부터 만들어보자.
// n : 4, m : 5
for (int roll = 0; roll < r; ++roll)
{
int topCnt = 0;
int rightCnt = m;
int bottomCnt = n;
int leftCnt = 0;
// n과 m 중에서 작은 거를 기준으로 한다.
int smallValue = n < m ? n : m;
int cnt = 0;
while (cnt < smallValue / 2)
{
++cnt;
int topIndex = topCnt;
// 위쪽 만들어보자.
for (int i = leftCnt; i < rightCnt - 1; ++i)
{
v2[topIndex][i] = v[topIndex][i + 1];
}
int rightIndex = rightCnt - 1;
// 오른쪽 만들어보자.
for (int i = topCnt; i < bottomCnt - 1; ++i)
{
v2[i][rightIndex] = v[i + 1][rightIndex];
}
// 아래쪽을 만들어보자.
int bottomIndex = bottomCnt - 1;
for (int i = rightCnt - 1; i > leftCnt; --i)
{
v2[bottomIndex][i] = v[bottomIndex][i - 1];
}
int leftIndex = leftCnt;
for (int i = bottomCnt - 1; i > topCnt; --i)
{
v2[i][leftIndex] = v[i - 1][leftIndex];
}
leftCnt++;
topCnt++;
rightCnt--;
bottomCnt--;
}
v = v2;
}
for (auto& iter : v2)
{
for (auto& iter2 : iter)
{
cout << iter2 << " ";
}
cout << endl;
}
// 6 6
}