[백준] 17822번 원판 돌리기 (자바 풀이)
- 알고리즘 문제 해결(PS)/[백준]
- 2022. 3. 21.
문제
https://www.acmicpc.net/problem/17822
풀이
단순 구현 문제이다. 꼼꼼히 작성하는 게 중요하다! 나는 이 문제를 다음과 같이 해결했다.
먼저, 원판은 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] == -1) continue; // 좌 우 체크 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] == -1) continue; 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+k > 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-k > 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 |
반응형
'알고리즘 문제 해결(PS) > [백준]' 카테고리의 다른 글
[백준] 1149번 RGB 거리 (자바 풀이) (0) | 2022.03.23 |
---|---|
[백준] 1022번 소용돌이 예쁘게 출력하기 (자바 풀이) (0) | 2022.03.22 |
[백준] 16926번 배열 돌리기 1 (자바 풀이) (0) | 2022.03.21 |
[백준] 1669번 멍멍이 쓰다듬기 (자바 풀이) (0) | 2022.03.11 |
[백준] 16946번 벽 부수고 이동하기4 (자바 풀이) (0) | 2022.03.10 |