레벨: 실버 2
문제번호: 17276
알고리즘: 구현
날짜: 2023년 12월 14일 오후 8:46
링크: https://www.acmicpc.net/problem/17276
시간 제한 | 메모리 제한 | 제출 | 정답 | 맞힌 사람 | 정답 비율 |
---|---|---|---|---|---|
3 초 | 512 MB | 1566 | 844 | 626 | 54.960% |
크기가 n x n인 2차원 정수 배열 X가 있다. (n은 홀수)
X를 45° 의 배수만큼 시계방향 혹은 반시계방향으로 돌리려고 한다. X를 시계 방향으로 45° 돌리면 아래와 같은 연산이 동시에 X에 적용되어야 한다:
반시계 방향으로 45° 돌리는 경우도 위와 비슷하게 정의된다.
예를 들어, 아래 그림 중앙에 5x5 배열 X가 있고, 이 배열을 시계방향 혹은 반시계방향으로 45° 돌렸을 때의 결과가 우측 그리고 좌측에 있다. 굵은 원소는 주 대각선 / 중간 열 / 부 대각선 / 중간 행에 위치한 원소이다.
입력으로 2차원 배열 X와 어느 방향으로 몇 도 회전할지 입력 받아, 그 결과를 출력하는 프로그램을 작성하시오.
첫 줄에 테스트 케이스의 수 T가 주어진다 (1 ≤ T ≤ 10).
각 테스트 케이스에 대해: 첫 줄에 배열의 크기를 나타내는 n (1 ≤ n < 500, n은 홀수) 그리고 각도 d가 주어진다. d는 0 ≤ |d| ≤ 360 을 만족하며 |d| 는 45의 배수이다. d가 양수이면 시계방향으로 d° 돌려야 하고, 음수이면 반시계방향으로 |d|° 돌려야 한다. 다음 n줄에 걸쳐 각 줄에 n개의 정수가 공백으로 구분되어 주어진다 (X의 원소들을 나타낸다). 각 값은 1 이상 1,000,000 이하의 정수이다.
각 테스트 케이스에 대해 회전 연산을 마친 후 배열의 상태를 출력한다. n줄에 걸쳐 각 줄에 n개의 정수를 공백으로 구분하여 출력한다.
4
5 45
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
5 -45
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
5 135
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
5 360
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
11 2 1 4 3
6 12 7 8 10
21 17 13 9 5
16 18 19 14 20
23 22 25 24 15
3 2 5 4 15
6 8 9 14 10
1 7 13 19 25
16 12 17 18 20
11 22 21 24 23
23 2 21 4 11
6 18 17 12 10
25 19 13 7 1
16 14 9 8 20
15 22 5 24 3
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
#include <iostream>
using namespace std;
int T;
int N;
int d;
int board[501][501];
int afterboard[501][501];
void turnright() {
//일단 그대로 복사
for (int y = 1; y <= N; y++) {
for (int x = 1; x <= N; x++) {
afterboard[y][x] = board[y][x];
}
}
//수정
for (int i = 1; i <= N; i++) {
afterboard[i][(N + 1) / 2] = board[i][i]; //주 대각선을 가운데 열로 복사
afterboard[i][N+1 - i] = board[i][(N + 1) / 2]; //가운데 열을 부 대각선으로 복사
afterboard[(N+1)/2][N+1-i] = board[i][N+1 - i]; //부 대각선을 가운데 행으로 복사
afterboard[i][i] = board[(N + 1) / 2][i]; //가운데 행을 주 대각선으로 복사
}
//다시 동작을 위한 afterboard를 board로 저장
for (int y = 1; y <= N; y++) {
for (int x = 1; x <= N; x++) {
board[y][x] = afterboard[y][x];
}
}
}
void turnleft() {
//일단 복사
for (int y = 1; y <= N; y++) {
for (int x = 1; x <= N; x++) {
afterboard[y][x] = board[y][x];
}
}
//수정
for (int i = 1; i <= N; i++) {
afterboard[(N + 1) / 2][i] = board[i][i]; //주 대각선을 가운데 행으로 복사
afterboard[i][i] = board[i][(N + 1) / 2]; //가운데 열을 주 대각선으로 복사
afterboard[i][(N + 1) / 2] = board[i][N+1 - i]; //부 대각선을 가운데 열로
afterboard[N+1 - i][i] = board[(N + 1) / 2][i]; //가운데 행을 부 대각선으로
}
//다시 동작을 위한 afterboard를 board로 저장
for (int y = 1; y <= N; y++) {
for (int x = 1; x <= N; x++) {
board[y][x] = afterboard[y][x];
}
}
}
int main() {
cin >> T;
for (int i = 0; i < T; i++) {
cin >> N >> d;
for (int y = 1; y <= N; y++) {
for (int x = 1; x <= N; x++) {
cin >> board[y][x];
}
}
while (d != 0) {
if (d > 0) {
turnright();
d -= 45;
}
else if (d < 0) {
turnleft();
d += 45;
}
}
for (int y = 1; y <= N; y++) {
for (int x = 1; x <= N; x++) {
cout<<board[y][x]<<" ";
}
cout << '\n';
}
}
return 0;
}