아.. 인덱스가 너무 헷갈리고 회전 레이어 다루는게 어려워서 어려운 문제가 아니었는데도 좀 고전했다..
다시 풀어봐야할 것 같다ㅜㅠ (확실히 구현에 좀 약한듯..)
우선, 회전 레이어 갯수는 N 또는 M 중 작은 값을 2로 나눈 값과 같다.
시작점은 (0,0), (1,1) ...로 되므로 이를 이용하여 시작점을 잡아주면 된다.
우선, 회전하는 방법을 잘 생각해야 하는데, 시작점을 0,0으로 잡았기 때문에 이를 temp 변수에 넣어주고 시작점부터 채워주기 시작한다.
[ 시작점부터 채우는 방향 ]
- 맨 윗줄 : 오 -> 왼 방향으로 채워준다
- 가장 오른쪽 열 : 아래 -> 위 방향으로 채워준다
- 맨 아랫줄 : 왼 -> 오 방향으로 채워준다
- 가장 왼쪽 열 : 위 -> 아래 방향으로 채워준다.
이 과정을 각 레이어마다 반복해주면 되는데, 그건 그냥 시작점, 끝점만 변경해주면 된다.
차례대로 코드를 살펴보자.
<편의상 가정>
- 현재 레이어는 0, 즉 가장 바깥 배열층을 돌리는 과정을 예시로 들겠다
- i는 행, 최댓값이 N이다.
- j는 열, 최댓값이 M이다.
1️⃣ 맨 윗줄 : 오 -> 왼 방향으로 채워준다
i는 0으로 고정, j만 차례대로 움직인다.
j는 0부터 시작해서 M-1전까지 증가한다.
바로 오른쪽 값을 왼쪽에 채워넣기 때문에 j+1인 값을 j에 넣어준다.
//i = 0
//j = 0 ~ M-1
arr[0][j] = arr[0][j+1]
2️⃣ 가장 오른쪽 열 : 아래 -> 위 방향으로 채워준다
이번엔 j가 최대값으로 고정, i만 차례대로 움직인다.
i는 0부터 시작해서 N-1전까지 증가한다.
바로 아래쪽 값을 위에 채워넣기 때문에 i+1인 값을 i에 넣어준다.
//i = 0 ~ N-1
//j = M-1
arr[i][j] = arr[i+1][j]
3️⃣ 맨 아랫줄 : 왼 -> 오 방향으로 채워준다
이번엔 i가 최대값으로 고정, j만 차례대로 움직인다.
j는 왼쪽값을 오른쪽에 넣어주기 때문에 최댓값부터 시작하고 점점 줄여나간다.
따라서 j값의 범위는 M-1부터 0 직전까지이다.
//i = N-1
//j = M-1 ~ 0
arr[i][j] = arr[i][j-1]
4️⃣ 가장 왼쪽 열 : 위 -> 아래 방향으로 채워준다.
이번엔 j는 다시 0으로 고정, i값만 차례대로 움직인다.
이전 i값을 넣어주기때문에 3번과 마찬가지로 최댓값부터 시작하고 점점 줄여나간다.
범위는 N-1부터 0직전까지이다.
//i = N-1 ~ 0
//j = 0
arr[i][j] = arr[i-1][j]
📌 각 (i, j의) 최댓값은 코드에서 iEdge, jEdge로 표현했으며 레이어를 반영해주기 위해 -layer한다.
📌 마지막 비워진 칸에는 temp에 저장해놓은 시작점을 넣어준다.
📌 마지막 비워진 칸은 시작점의 바로 밑 칸이기 때문에 arr[layer+1][layer]가 된다.
< 코드 >
#include <iostream>
using namespace std;
/*
<문제 정리>
크기 N*M 배열 반시계로 회전 -> R번 회전시킨 결과 출력
*/
#define MAX 301
int arr[MAX][MAX];
int N, M, R;
void rotation(int layer)
{
int temp = arr[layer][layer];
int iEdge = N-layer-1, jEdge = M-layer-1;
// 오->왼, 아->위, 왼->오, 위->아 순서대로 진행
// layer = circle
// 오른쪽에서 왼쪽으로 채우기
for (int j = layer; j < jEdge; j++)
arr[layer][j] = arr[layer][j+1];
// 아래쪽에서 위쪽으로 채우기
for(int i=layer; i<iEdge; i++)
arr[i][jEdge] = arr[i+1][jEdge];
// 왼쪽에서 오른쪽으로 채우기
for(int j=jEdge; j>layer; j--)
arr[iEdge][j] = arr[iEdge][j - 1];
// 위쪽에서 아래쪽으로 채우기
for(int i=iEdge; i>layer; i--)
arr[i][layer] = arr[i-1][layer];
// 마지막 비워진 칸에 temp 넣기
arr[layer+1][layer] = temp;
}
int main(void)
{
ios::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
cin >> N >> M >> R;
for(int i=0; i<N; i++) {
for(int j=0; j<M; j++) {
cin >> arr[i][j];
}
}
int layers = min(N, M) / 2;
for(int i=0; i<R; i++) {
for(int layer=0; layer<layers; layer++) rotation(layer);
}
for(int i=0; i<N; i++) {
for(int j=0; j<M; j++) {
cout << arr[i][j] << " ";
}
cout << '\n';
}
return 0;
}
'Algorithm > 백준과 프로그래머스' 카테고리의 다른 글
[C++] 20291. 파일정리 (0) | 2024.03.13 |
---|---|
[C++] 16234. 인구이동 (0) | 2024.03.07 |
[C++] 17413. 단어 뒤집기2 (0) | 2024.03.06 |
[프로그래머스/C++] LV2. 기능개발 (0) | 2024.02.02 |
[프로그래머스] LV1. 키패드 누르기 (0) | 2024.01.19 |