https://www.acmicpc.net/problem/16927

[필자 사고]
재미난 문제다.
필자는 달팽이 문제에 약했따.
ㅇㅣ 문제를 풀면서 어느정도 감을 익힐 수 있었다.
달팽이 문제의 핵심은 layer를 만드는 일이다.
layer 만드는 공식은 min(N,M)/2 를 하게 되면 총 layer갯수를 구할 수 있다.
layer 별로 회전을 진행한다.
height 및 width 의 크기를 구한뒤 주기를 구할 수 있고 그로인해 중복되는 회전을 막을 수 있다.
Rotate() 함수를 살펴보자.
layer와 회전수와 관련된 매개변수를 받은 뒤
top, bottom, left , right 의 열과 행들을 입력받은다.
그 다음 4개의 for문을 이용하여 회전을 진행해준다.
마지막에 temp값은 반드시 넣어주자. 반시계나 시계방향 회전에 따라 달라질 수 있음 유도리있게
아래는 자세한 코드 해설이다.
[코드 해설]
Input()
- 사용자 입력을 받아서 N(행), M(열), R(회전 횟수)을 저장한다.
- arr 2차원 벡터를 N × M 크기로 초기화한 뒤, 행렬의 각 원소를 입력받아 저장한다.
RotateLayer(int layer, int count)
- 하나의 레이어(테두리)를 count번 반시계 방향으로 회전시키는 함수.
- top, left, bottom, right는 현재 레이어의 경계 인덱스다.
- 회전은 다음 순서로 진행된다:
- arr[top][left] 값을 first에 저장한다. (맨 앞 원소 보존)
- 위쪽 행의 원소들을 왼쪽으로 한 칸씩 이동시킨다.
- 오른쪽 열의 원소들을 위쪽으로 한 칸씩 이동시킨다.
- 아래쪽 행의 원소들을 오른쪽으로 한 칸씩 이동시킨다.
- 왼쪽 열의 원소들을 아래쪽으로 한 칸씩 이동시킨다.
- 처음 저장한 first 값을 arr[top+1][left] 위치에 넣어서 순환을 완성한다.
RotateCounterClockWise()
- 배열 전체를 반시계 방향으로 회전시키는 함수.
- 배열은 여러 겹의 레이어(테두리)로 구성되므로, min(N, M) / 2만큼의 레이어가 생긴다.
- 각 레이어마다:
- 레이어의 높이(height)와 너비(width)를 계산한다.
- 둘레의 길이(parameter = 2*(height+width)-4)를 구한다.
- 실제로 필요한 회전 횟수(R % parameter)를 구한다.
- RotateLayer를 호출하여 해당 레이어를 회전시킨다.
Print()
- 현재 arr 배열의 상태를 행렬 형태로 출력한다.
- 각 행마다 원소를 공백으로 구분하여 출력하고, 줄바꿈을 수행한다.
Game_Start()
- 배열 회전의 전체 흐름을 관리하는 함수.
- RotateCounterClockWise()를 호출하여 배열을 회전시킨 뒤,
- 최종 결과를 Print()를 통해 출력한다.
main()
- 입출력 속도를 빠르게 하기 위해 ios::sync_with_stdio(false)와 cin.tie(nullptr)을 설정한다.
- Input()으로 데이터를 입력받고, Game_Start()를 호출하여 프로그램을 실행한다.
[소스 코드]
#include <iostream>
#include <vector>
using namespace std;
int N, M, R;
vector<vector<int>> arr;
void Input() {
cin >> N >> M >> R;
arr.assign(N, vector<int>(M));
for (int i = 0; i < N; i++) {
for (int k = 0; k < M; k++) {
cin >> arr[i][k];
}
}
}
void RotateLayer(int layer, int count) {
int top = layer;
int left = layer;
int bottom = N - layer - 1;
int right = M - layer - 1;
for (int r = 0; r < count; r++) {
int first = arr[top][left];
for (int j = left; j < right; j++) {
arr[top][j] = arr[top][j + 1];
}
for (int j = top; j < bottom; j++) {
arr[j ][right] = arr[j+1][right];
}
for (int j = right; j > left; j--) {
arr[bottom][j] = arr[bottom][j - 1];
}
for (int j = bottom; j > top; j--) {
arr[j][left] = arr[j-1][left];
}
arr[top+1][left] = first;
}
}
void RotateCounterClockWise() {
int layer = min(N, M) / 2;
for (int i = 0; i < layer; i++) {
int height = N - 2 * i;
int width = M - 2 * i;
int parameter = 2 * (height + width) - 4;
int rotateCount = R % parameter;
RotateLayer(i, rotateCount);
}
}
void Print() {
for (int i = 0; i < N; i++) {
for (int k = 0; k < M; k++) {
cout << arr[i][k] << " ";
}
cout << "\n";
}
}
void Game_Start() {
RotateCounterClockWise(); // 최적화된 회전
Print();
}
int main(void) {
ios::sync_with_stdio(false);
cin.tie(nullptr);
Input();
Game_Start();
}'백준 > 구현' 카테고리의 다른 글
| 백준 1025 c++ "제곱수 찾기" -PlusUltraCode- (0) | 2025.09.28 |
|---|---|
| 백준 7490 c++ "0 만들기" -PlusUltraCode- (0) | 2025.09.27 |
| 백준 16918 c++ "봄버맨" -PlusUltraCode- (0) | 2025.09.24 |
| 백준 17086 c++ "아기 상어 2" -PlusUltraCode- (0) | 2025.09.23 |
| 백준 3085 c++"사탕 게임" -PlusUltraCode- (0) | 2025.09.21 |