코테/백준

[백준/JAVA] 16926번: 배열 돌리기 1

imname1am 2023. 12. 17. 00:16
반응형

📖 문제

 

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

 

💡  풀이 방식

• 구현

행과 열 중 더 작은 값 / 2한 길이까지 대각선의 값을 이용해 회전 시작점을 잡는다. (i, i). 한 겹씩 회전

(i,i)를 시작점으로 잡고, 마지막 값은 빠뜨릴 수 있으므로 미리 변수로 따로 저장해둔다.

int lastVal = map[i][i];

 

현재 회전 방향이 4보다 작다면 (= 회전 방향을 한 바퀴 돌지 않았다면) 이동시키도록 한다.

 - 회전시켰을 때 만약 값의 범위를 벗어난다면, 이동 방향을 바꾼다.

 - 회전시켜도 범위 내에 있는 값이라면 그쪽으로 이동시킨다.

int idx = 0;	// 방향 인덱스

while(idx < 4) {	// 방향 배열을 한 바퀴 다 돌기 전까지
	int nx = x + dx[idx];
    int ny = y + dy[idx];
    
    if(nx >= i && nx < N - i && ny >= i && ny < M - i) {	// 범위 내에 있으면, 회전시키기
    	map[x][y] = map[nx][ny];
        x = nx;
        y = ny;
    }
    else {	// 범위 내에 없으면, 방향 전환
    	idx++;
    }
}

 

 

빼놓은 마지막 값을 넣는다.

map[i + 1][i] = lastVal;

 

 

💥 유의사항

설정한 범위를 벗어나지 않는지 잘 확인해야 한다.

i <= nx && nx < N - i && i <= ny && ny < M - i

 

 

🔺 코드

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
import java.util.*;
import java.io.*;
 
public class Main {
    static int[] dx = {010-1};   // 반시계 방향 (서 북 동 남)
    static int[] dy = {10-10};
    
    static int N, M, R;
    static int min;
    static int[][] map;
    
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine(), " ");
        
        // 입력받기
        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());
        R = Integer.parseInt(st.nextToken());
        
        map = new int[N][M];
        for(int i = 0 ; i < N ; i++) {
            st = new StringTokenizer(br.readLine(), " ");
            for(int j = 0 ; j < M ; j++) {
                map[i][j] = Integer.parseInt(st.nextToken());
            }
        }
        
        min = Math.min(N, M);   // 행,열 중 더 작은 것 구하기
        
        // R번 회전시키기
        while(R --> 0) {
            rotate();
        }
 
        // 출력하기
        print();
    }
    
    private static void rotate() {
        for(int i = 0 ; i < min / 2 ; i++) {
            int x = i;
            int y = i;
            
            int lastVal = map[x][y];   // 마지막에 넣을 값 미리 빼놓
            
            int idx = 0;
            
            while(idx < 4) {
                int nx = x + dx[idx];
                int ny = y + dy[idx];
                
                if(i <= nx && nx < N - i && i <= ny && ny < M - i) {
                    map[x][y] = map[nx][ny];
                    x = nx;
                    y = ny; 
                }
                else {
                    idx++;
                }
            }
            
            map[i + 1][i] = lastVal;    // 빼놓은 마지막 값 넣기
        }
    }
    
    private static void print() {
        StringBuilder sb = new StringBuilder();
        
        for(int[] i : map) {
            for(int j : i) {
                sb.append(j + " ");
            }
            sb.append("\n");
        }
        System.out.println(sb);        
    }
}
 
cs

 

 

➕ 다른 풀이 방식

각 횟수마다 한 라인의 위쪽, 오른쪽, 아래쪽, 왼쪽 순으로 반시계 방향으로 스와이프 하게 하시고 푸셨다.

 

[백준 16926] 배열 돌리기1(Java)

https://www.acmicpc.net/problem/16926 16926번: 배열 돌리기 1 크기가 N×M인 배열이 있을 때, 배열을 돌려보려고 한다. 배열은 다음과 같이 반시계 방향으로 돌려야 한다. A[1][1] ← A[1][2] ← A[1][3] ← A[1][4] ←

wiselog.tistory.com

 


💦 어려웠던 점

- 대각선 (i,i) 위치로 이동을 어떻게 하지?

- 한 겹씩만 어떻게 돌게 하지?

 

🧐 새로 알게 된 내용

- 해당 위치 값을 반시계 방향 (남동서북)으로 밀어서 이동시키려고 했는데,

그게 아니고 해당 위치에서 값을 끌어오는 식으로 진행해서 서북동남 순으로 dx/dy 배열을 저장하고 진행하신 듯 하다.

 

 

1회독 2회독 3회독 4회독 5회독
V 12.23      

 

 

(+12.23 2회독)

중간에 꼬여서 어디서 틀렸나..하고 기존 풀이를 봤다..

복습 다시해야혀^^ (54분)

코드 확인하기
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
import java.util.*;
import java.io.*;
 
public class Main {
    static int[] dx = {010-1};   // 반시계 방향
    static int[] dy = {10-10};
    
    static int N, M, R;
    static int[][] board;
    
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine(), " ");
        
        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());
        R = Integer.parseInt(st.nextToken());
        
        board = new int[N][M];
        for(int i = 0 ; i < N ; i++) {
            st = new StringTokenizer(br.readLine(), " ");
            for(int j = 0 ; j < M ; j++) {
                board[i][j] = Integer.parseInt(st.nextToken());
            }
        }
        
        while(R --> 0) {
            rotate();
        }
        
        StringBuilder sb = new StringBuilder();
        for(int[] i : board) {
            for(int j : i) {
                sb.append(j + " ");
            }
            sb.append("\n");
        }
        System.out.println(sb);
    }
    
    private static void rotate() {
        for(int i = 0 ; i < Math.min(N, M) / 2 ; i++) {
            int x = i;
            int y = i;
            
            int lastVal = board[x][y];  // 마지막 위치 빠지므로 따로 저장
            
            int idx = 0;
            while(idx < 4) {
                // 값 끌어와서 채우기
                int nx = x + dx[idx];
                int ny = y + dy[idx];
                
                if(!inRange(i, nx, ny)) {
                    idx++;
                }
                else {
                    board[x][y] = board[nx][ny];
                    x = nx;
                    y = ny;
                }
            }
            
            board[x + 1][y] = lastVal;  // 따로 저장한 값 채우기
        }
    }
    
    private static boolean inRange(int i, int x, int y) {
        return (i <= x && x < N - i && i <= y && y < M - i);
    }
}
 
cs

 


(참고)

✔ 풀이 참고

 

[백준] 16926: 배열 돌리기 1 (Java)

BOJ 16926: 배열 돌리기 1 https://www.acmicpc.net/problem/16926회전시킬 수 있는 그룹 별로 반시계 방향으로 회전시킨다.회전시켜야 하는 그룹의 갯수를 구한다.Math.min(N, M) / 2예를 들어, 2 X 2 행렬에서는

velog.io

 

백준 16926 배열 돌리기 1 (Java)

1. 문제 링크 16926번: 배열 돌리기 1 크기가 N×M인 배열이 있을 때, 배열을 돌려보려고 한다. 배열은 다음과 같이 반시계 방향으로 돌려야 한다. A[1][1] ← A[1][2] ← A[1][3] ← A[1][4] ← A[1][5] ↓ ↑ A[2]

daon-programming.tistory.com

 

반응형