https://www.acmicpc.net/problem/16926
16926번: 배열 돌리기 1
크기가 N×M인 배열이 있을 때, 배열을 돌려보려고 한다. 배열은 다음과 같이 반시계 방향으로 돌려야 한다. A[1][1] ← A[1][2] ← A[1][3] ← A[1][4] ← A[1][5] ↓ ↑ A[2][1] A[2][2] ← A[2][3] ← A[2][4] A[2][5]
www.acmicpc.net
구현 문제를 잘 못 푸는 나에게 어려웠던 문제이다. 기본적인 배열 돌리기도 힘들어하다니.. 연습이 시급하다.
생각해볼 포인트는 두 가지이다.
1. 구현의 영역인 배열의 값을 한 칸씩 반시계 방향으로 옮기기
2. 사각형 모양의 배열들이 독립적으로 회전해야 하는 것
이런 식으로, 외곽 배열과 내부 배열은 독립적으로 회전한다.
잘 생각해서, 인덱스 접근만 잘한다면 나머지는 배열의 값을 이동하면 된다.
1. 반시계 방향으로 배열의 값을 돌리기
- 이 부분은, 동서남북 방향 모두 각각 옮겨줘야 한다.
- 위의 사진을 참고하면, [1][1] ~ [1][5], [1][5] ~ [4][5], [4][5] ~ [4][1], [4][1] ~ [1][1]으로 인덱스를 계산해주면 된다.
- 제일 외곽은 0~x-1, 0~y-1이지만 내부 사각형은 1칸씩 줄어드는 것을 생각해야 한다.
(최소, 최대 모두 1씩 감소시켜줘야 한다)
2. 독립적으로 회전, 얼마나 회전?
- 문제의 조건을 생각해보면,
- min(N, M) mod 2 = 0
가 등장한다. 즉, 가로 또는 세로의 최솟값은 짝수이고, 해당 값을 2로 나눈 값이 사각형의 개수를 결정한다.
#include <iostream>
#include <cmath>
using namespace std;
int n, m, r;
int arr[301][301];
void rotation(int x, int y) {
int count = min(x, y) / 2;
for (int c = 0; c < count; c++) {
int xMax = x - c - 1;
int yMax = y - c - 1;
int start = arr[c][c];
for (int j = c; j < yMax; j++) { // 왼 <- 오
arr[c][j] = arr[c][j + 1];
}
for (int i = c; i < xMax; i++) { // 위 <- 아래
arr[i][yMax] = arr[i+1][yMax];
}
for (int j = yMax; j > c; j--) { // 오 <- 왼
arr[xMax][j] = arr[xMax][j-1];
}
for (int i = xMax; i > c; i--) { // 아래 <- 위
arr[i][c] = arr[i-1][c];
}
arr[c + 1][c] = start; // 시작값으로 바꿔주기
}
}
int main() {
cin >> n >> m >> r;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
cin >> arr[i][j];
}
}
for (int i = 0; i < r; i++) {
rotation(n, m);
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
cout << arr[i][j] << " ";
}
cout << "\n";
}
}
'문제 풀이 > 백준 알고리즘' 카테고리의 다른 글
[baekjoon 14888] 연산자 끼워넣기(브루트포스, 백트래킹) (C++) (0) | 2022.02.25 |
---|---|
[baekjoon 1939] 중량제한 (파라매트릭서치, BFS) (C++) (0) | 2022.02.20 |
[baekjoon 22867] 종점 (스위핑, 문자열, 정렬) (C++) (0) | 2021.10.08 |
[baekjoon 22860] 폴더 정리(small) (DFS, BFS, 구현, HashMap) (C++) (0) | 2021.10.05 |
[baekjoon 14503] 로봇 청소기 (구현, 시뮬레이션) (C++) (0) | 2021.09.24 |