알고리즘/백준
[C++] 백준 16926 : 배열 돌리기 1
금호박
2025. 1. 30. 00:15
문제
https://www.acmicpc.net/problem/16926
풀이
(0,0) -> (1,1) -> (2,2) -> ... -> (b,b) 까지 각 줄을 규칙대로 이동시킨다. (<- for 문 이용하여 구현함)
1. 윗 줄을 왼쪽으로 이동
2. 왼쪽 줄을 아래로 이동
3. 맨 아래쪽 줄을 오른쪽으로 이동
4. 오른쪽 줄을 위쪽으로 이동
이때 b = min(n,m) / 2 로 계산된다.
코드
#include <iostream>
#include <math.h>
using namespace std;
int n, m, r;
int a[300][300];
int ans[300][300];
void turn(){
int b = min(n,m) / 2;
for(int i=0,j=0; i<b,j<b; i++,j++){
// 윗 줄을 왼쪽으로 이동
for(int x = m-j; x >= j+1; x--){
ans[i][x-1] = a[i][x];
}
// 왼쪽 줄을 아래로 이동
for(int y = i; y<n-i-1; y++){
ans[y+1][j] = a[y][j];
}
// 맨 아래쪽 줄을 오른쪽으로 이동
for(int x = j; x<m-j-1; x++){
ans[n-i-1][x+1] = a[n-i-1][x];
}
// 오른쪽 줄을 위로 이동
for(int y = n-i-1; y>=i+1; y--){
ans[y-1][m-j-1] = a[y][m-j-1];
}
}
// 원본 배열에 결과 저장
for(int i=0; i<n; i++){
for(int j=0; j<m; j++){
a[i][j] = ans[i][j];
}
}
}
int main()
{
cin >> n >> m >> r;
for(int i=0; i<n; i++){
for(int j=0; j<m; j++){
cin >> a[i][j];
}
}
//int cnt = r % ((n-1 + m-1) *2); // 회전시켜야 하는 횟수 <- 틀렸다.
int cnt = r;
for(int i=0; i<cnt; i++){
turn();
}
for(int i=0; i<n; i++){
for(int j=0; j<m; j++){
cout << a[i][j]<<" ";
}
cout << "\n";
}
return 0;
}
메모
정말 쌩 구현 문제였던 것 같다. 구현이 생각보다 쉽지 않았고, 특히 index를 고려할 때 실수하기 쉬웠던 것 같다. ㅜㅜ
(메모장으로 정리하는데~~ 막 어지러웠다~~ ㅜㅜ ^^;;)
그리고 나의 경우 예를 들어 100번 회전시킨 것과 4번 회전시킨 결과가 같은 경우를 고려해서 회전 횟수를 줄여보려고 시도했는데, 이 경우 틀렸다고 뜬다.
(0,0) 에서 옮겨야 하는 원소의 수, (1,1)에서 옮겨야 하는 원소의 수~ 이것이 경우에 따라 결론적으로 공배수 단위가 될 수도 있고, 안될 수도 있다. 그래서 원래 int cnt = r % ((n-1 + m-1) *2); 로 회전 횟수를 줄여보려고 했지만, 틀렸다는 결과가 나왔다. 실제로 찾아낸 대부분의 테스트 케이스에서 정상적으로 작동하는 것이 확인되었기 때문에 더욱 어디가 틀렸는지를 찾기가 어려웠다. 하지만 cnt를 입력받은 r 그대로 이용했을 떄에는 맞았다고 뜨는 것을 확인할 수 있었다.
시간 초과가 날까 걱정되어서 cnt 수를 줄여보려 했던 것인데, 이 경우 오히려 틀린 결과가 나올 수 있다는 점을 간과했다. 좀 더 여러 상황을 생각해보고 이런 시도를 해보면 좋을 것 같고, 일단 시간 초과가 날까 염려 정도가 되는 것이라면 그냥 제출해본 후 시간초과가 났을 때 어떻게 해결할지 고민해보는 것도 좋겠다. (확실하진 않은 경우에)