티스토리 뷰
#include <stdio.h>
int ii,ij,oi,oj,ptr,ri,rj,l,cnt,od,id;
void f0(void) { //입력 배열 회전
if(id==0) {++ii;if(ii >= ri) ii = ri, id=1;}
else if(id==1) {++ij;if(ij >= rj) ij = rj, id=2;}
else if(id==2) {--ii;if(ii <= l) ii = l, id=3;}
else if(id==3) {--ij;if(ij <= l) ij = l, id=0;}
}
void f1(void) { //출력 배열 회전
if(od==0) {++oi;if(oi >= ri) oi=ri, od=1;}
else if(od==1) {++oj;if(oj >= rj) oj=rj, od=2;}
else if(od==2) {--oi;if(oi <= l) oi = l, od=3;}
else if(od==3) {--oj;if(oj <= l) oj = l, od=0;}
}
int main(void) {
//입력
int n,m,k,tmp_n, tmp_m, tmp_k;
scanf("%d %d %d",&n,&m,&k);
tmp_n = n, tmp_m = m;
int arr[n][m], ans[n][m];
for(int i=0; i<n; i++)
for(int j=0; j<m; j++)
scanf("%d", &arr[i][j]);
//배열회전
int min = (n<m) ? n : m; //행 열 중 작은 값을 골라서
min /= 2; //2만큼 나눠준 것이 회전시켜야할 부분 배열의 개수입니다.
ptr = 0, ri = n-1, rj = m-1, l=0;
while(ptr < min) { //배열 회전 main
ii=ptr,ij=ptr,oi=ptr,oj=ptr,od=0,id=0,cnt = 2*(tmp_n + tmp_m -2);
tmp_k = k % cnt; //부분배열의 요소의 개수로 mod을 합니다.
for(int i=0; i<tmp_k; i++) f1(); //회전 후 입력 받았을때의, 좌상단 요소의 위치를 구합니다.
while(cnt--) { //출력 배열에 입력 배열의 요소들을 순서대로 넣어줍니다.
f0(), f1();
ans[oi][oj] = arr[ii][ij];
}
tmp_n -= 2, tmp_m -= 2; //다음 배열로
++l, --ri, --rj, ++ptr; //다음 배열로
}
//출력
for(int i=0; i<n; i++) {
for(int j=0; j<m; j++) printf("%d ", ans[i][j]);
printf("\n");
}
}

(1) 배열을 차례차례 바깥 부터 회전 시킵니다.
이 때 회전 시켜야 할 부분 배열의 개수는 min(행, 열) / 2 입니다.
(2) k번 회전이나, 부분 배열의 개수보다 더 많이 회전하는 것은 의미가 없으므로
k mod (부분 배열의 개수) 만큼 회전만 하면 됩니다. (많이 하면 시간이 더 걸립니다)
(3) 부분 배열의 좌상단이 (2)번에서 구한 만큼 회전하면 어디에 있을지를 구해야 합니다.

이것을 예로 들면 좌상단에 있던 1이 우하단으로 갔습니다. 위의 코드에서는 회전을 하면서 이때의 인덱스 (x, y) 값을 구합니다.
(4) 입력배열은 좌상단을 기준으로, 출력배열은 (3)에서 구한 (x,y) 점을 시작으로, 부분배열의 개수만큼 회전하면서, 하나씩 입력배열에 있는 것을 출력배열에 대입합니다. 이렇게 하면 출력배열에는 입력배열이 회전된 상태가 저장하게 됩니다.
<부록1> 변수 설명

l, ri, rj는 부분배열의 좌상단과, 우상단의 인덱스를 나타냅니다 (좌상단은 변수 하나로 나타내는 이유는 행과 열의 값이 같기 때문입니다)
ii, ij, id 는 입력배열의, 행, 열, 그리고 회전을 할 때 사용하는 진행방향을 의미합니다.
oi, oj, od도 출력배열용 변수입니다.
<부록2> 회전 함수 설명
void f0(void) { //입력 배열 회전
if(id==0) {++ii;if(ii >= ri) ii = ri, id=1;}
else if(id==1) {++ij;if(ij >= rj) ij = rj, id=2;}
else if(id==2) {--ii;if(ii <= l) ii = l, id=3;}
else if(id==3) {--ij;if(ij <= l) ij = l, id=0;}
}
반시계방향으로 돌면서, 처음엔 아래로, 그다음 오른쪽, 그리고 위로, 마지막은 왼쪽으로 갑니다.
더이상 나아갈수 없다면 방향을 바꿉니다.
여기서 == 가 아니라 >= 을 그리고 굳이 방향만 바꾸는 것이 아니라, 인덱스값을 다시 지정해 준 이유는

이렇게 오른쪽, 왼쪽으로 이동하면 다른곳으로 넘어가버리기 때문에 방향을 바꿔주면서, 넘어가지는 않게 인덱스 값을 설정해준 것입니다.
'c언어 > BAEKJOON' 카테고리의 다른 글
c언어 2243번 사탕상자 (백준) (0) | 2024.08.03 |
---|---|
c언어 17470번 배열 돌리기 5 (백준) (0) | 2024.07.15 |
c언어 10464번 XOR (백준) (0) | 2024.03.20 |
c언어 27295번 선형 회귀는 너무 쉬어 1 (백준) (0) | 2024.01.17 |
c언어 17087번 숨바꼭질 6 (백준) (0) | 2024.01.17 |
- Total
- Today
- Yesterday
- C언어
- BFS
- 누적합
- 누적 합
- 그리디
- 최소 스패닝 트리
- java
- C++
- 플로이드
- XOR
- 1835
- DFS
- 기하학
- DP
- 정렬
- 브루트포스
- 스택
- 최대공약수
- 그래프
- Lazy Propagation
- 1835번
- 백준
- PASCAL
- 덱
- 세그먼트 트리
- union
- find
- Krustal
- 오프라인 쿼리
- Segment Tree
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |