[백준] 17822번 원판 돌리기 (자바 풀이)

문제

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

 

17822번: 원판 돌리기

반지름이 1, 2, ..., N인 원판이 크기가 작아지는 순으로 바닥에 놓여있고, 원판의 중심은 모두 같다. 원판의 반지름이 i이면, 그 원판을 i번째 원판이라고 한다. 각각의 원판에는 M개의 정수가 적혀

www.acmicpc.net

 

풀이

단순 구현 문제이다. 꼼꼼히 작성하는 게 중요하다! 나는 이 문제를 다음과 같이 해결했다.

 

먼저, 원판은 2차원 배열 circle [][]을 이용해서 표현했다. 이후 두 가지 함수를 작성했다.

 

1. 원판을 돌리는 함수

-> 시계, 반시계 방향을 기준으로 원판의 숫자를 돌린다. 인덱스 계산을 잘해야 한다.

 

2. 숫자를 지우는 함수

-> 모든 원소를 돌며 상하좌우를 탐색해 같은 원소가 있다면 boolean check[][] 배열에 체크해놓는다. 이후 check[][] 배열을 돌면서 해당 원소를 -1로 바꿔준다. 만약 바꿀 원소가 없다면 평균값을 구하여 평균보다 작은 수는 +1 해주고 작은 수는 -1 해준다. 이때 중요한 것은 평균과 같은 숫자는 아무 작업도 하면 안된다! 또한 평균은 double 형태로 구해야 한다.

 

이렇게 두 가지 함수를 이용하면 해결 할 수 있다.

 

코드

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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
import java.io.*;
import java.util.*;
public class Baekjoon_17822 {
    static int N,M,T;
    static int circle[][];
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        
        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());
        T = Integer.parseInt(st.nextToken());
        
        circle = new int[N+1][M+1];
        
        for(int i=1; i<=N; i++) {
            st = new StringTokenizer(br.readLine());
            for(int j=1; j<=M; j++) {
                circle[i][j] = Integer.parseInt(st.nextToken());
            }
        }
        for(int i=0; i<T; i++) {
            st = new StringTokenizer(br.readLine());
            int x = Integer.parseInt(st.nextToken());
            int d = Integer.parseInt(st.nextToken());
            int k = Integer.parseInt(st.nextToken());
            rotate(x,d,k);
            erase();
        }
        
        int ans = 0;
        for(int i=1; i<=N; i++) {
            for(int j=1; j<=M; j++) {
                if(circle[i][j] != -1) {
                    ans += circle[i][j];
                }
            }
        }
        System.out.println(ans);
    }
    
    public static void erase() {
        boolean check[][] = new boolean[N+1][M+1];
        
        for(int i=1; i<=N; i++) {
            for(int j=1; j<=M; j++) {
                if(circle[i][j] == -1continue;
                // 좌 우 체크
                int left = (j-1> 0 ? j-1 : M;
                if(circle[i][j] == circle[i][left]) {
                    check[i][j] = true;
                    check[i][left] = true;
                }
                int right = (j+M+1)%M;
                if(circle[i][j] == circle[i][right]) {
                    check[i][j] = true;
                    check[i][right] = true;
                }
                // 상 하 체크
                int up = i+1;
                if(up<=N) {
                    if(circle[i][j] == circle[up][j]) {
                        check[i][j] = true;
                        check[up][j] = true;
                    }
                }
                int down = i-1;
                if(down > 0) {
                    if(circle[i][j] == circle[down][j]) {
                        check[i][j] = true;
                        check[down][j] = true;
                    }
                }
            }
        }
        
        boolean eraseFlag = false;
        int sum = 0;
        int cnt = 0;
        for(int i=1; i<=N; i++) {
            for(int j=1; j<=M; j++) {
                if(check[i][j]) {
                    eraseFlag = true;
                    circle[i][j] = -1;
                }else {
                    if(circle[i][j] != -1) {
                        sum += circle[i][j];
                        cnt++;
                    }
                }
            }
        }
        if(eraseFlag) return;
        /* 삭제한 수가 없으면 */
        
        double avg = (double)sum/(double)cnt;
        for(int i=1; i<=N; i++) {
            for(int j=1; j<=M; j++) {
                if(circle[i][j] == -1continue;
                
                if(circle[i][j] > avg ) {
                    circle[i][j] -= 1;
                }else if(circle[i][j] < avg){
                    circle[i][j] += 1;
                }
            }
        }
    }
    
    public static void rotate(int x, int d, int k) {
        int num = x;
        if(d == 0) {    // 시계 방향 회전
            while(num <= N) {
                int temp[] = new int[M+1];
                for(int i=1; i<=M; i++) {
                    int next = i+> M ? i+k-M : i+k; 
                    temp[next] = circle[num][i];
                }
                for(int i=1; i<=M; i++) {
                    circle[num][i] = temp[i];
                }
                num += x;
            }
        }else {    // 반시계 방향 회전
            while(num <= N) {
                int temp[] = new int[M+1];
                for(int i=M; i>=1; i--) {
                    int next = i-> 0 ? i-k : i-k+M;
                    temp[next] = circle[num][i];
                }
                for(int i=1; i<=M; i++) {
                    circle[num][i] = temp[i];
                }
                num += x;
            }
        }
    }
}
cs

 

반응형

댓글

Designed by JB FACTORY