Skip to content

Commit 07bd7bb

Browse files
authored
[백준 17822] 원판 돌리기 - 시뮬레이션
1 parent 59abb6a commit 07bd7bb

File tree

1 file changed

+166
-0
lines changed

1 file changed

+166
-0
lines changed

hoseok/week35/Boj17822.java

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
/*
2+
원판은 2차원 배열로 나타낼 수 있음
3+
하나의 원판에서의 인접은 N열은, N - 1열과 1열과 인접하다는 것과, i행은, i + 1행, i - 1행과 인접하다는것으로 표현됨
4+
즉, 2차원 배열에서 열들은 순환함
5+
6+
- 시계 방향 N칸 회전 -> 배열에서 열을 N칸씩 우로 이동
7+
- 반시계 방향 N칸 회전 -> 배열에서 열을 N칸씩 좌로 이동
8+
9+
원판에 수가 남아 있으면, 인접하면서 수가 같은 것을 모두 찾는다. (BFS)
10+
그러한 수가 있는 경우에는 원판에서 인접하면서 같은 수를 모두 지운다.
11+
없는 경우에는 원판에 적힌 수의 평균을 구하고, 평균보다 큰 수에서 1을 빼고, 작은 수에는 1을 더한다.
12+
*/
13+
import java.io.*;
14+
import java.util.*;
15+
16+
class Main {
17+
18+
static class Node {
19+
int r, c;
20+
21+
Node(int r, int c) {
22+
this.r = r;
23+
this.c = c;
24+
}
25+
}
26+
27+
private static final int[] rows = {-1, 0, 1, 0};
28+
private static final int[] cols = {0, 1, 0, -1};
29+
30+
private static int n, m, t;
31+
private static int[][] map;
32+
33+
public static void main(String[] args) throws Exception {
34+
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
35+
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
36+
StringTokenizer st = new StringTokenizer(br.readLine());
37+
38+
n = Integer.parseInt(st.nextToken());
39+
m = Integer.parseInt(st.nextToken());
40+
t = Integer.parseInt(st.nextToken());
41+
42+
map = new int[n][m];
43+
for (int i = 0; i < n; i++) {
44+
st = new StringTokenizer(br.readLine());
45+
for (int j = 0; j < m; j++) {
46+
map[i][j] = Integer.parseInt(st.nextToken());
47+
}
48+
}
49+
50+
while (t-- > 0) {
51+
st = new StringTokenizer(br.readLine());
52+
int x = Integer.parseInt(st.nextToken());
53+
int d = Integer.parseInt(st.nextToken());
54+
int k = Integer.parseInt(st.nextToken());
55+
56+
if (d == 0) {
57+
rotate(x, k);
58+
} else {
59+
rotate(x, -k);
60+
}
61+
62+
// 원판에 수가 있다면 지우기
63+
boolean hasNearNumber = false;
64+
boolean[][] visited = new boolean[n][m];
65+
for (int i = 0; i < n; i++) {
66+
for (int j = 0; j < m; j++) {
67+
if (!visited[i][j] && map[i][j] != 0) {
68+
hasNearNumber |= bfs(visited, new Node(i, j));
69+
}
70+
}
71+
}
72+
73+
if (!hasNearNumber) {
74+
updateNumber();
75+
}
76+
}
77+
78+
int sum = 0;
79+
for (int i = 0; i < n; i++) {
80+
for (int j = 0; j < m; j++) {
81+
sum += map[i][j];
82+
}
83+
}
84+
85+
bw.write(sum + "");
86+
bw.flush();
87+
bw.close();
88+
}
89+
90+
91+
public static void updateNumber() {
92+
int count = 0;
93+
int sum = 0;
94+
for (int i = 0; i < n; i++) {
95+
for (int j = 0; j < m; j++) {
96+
if (map[i][j] != 0) {
97+
count++;
98+
}
99+
sum += map[i][j];
100+
}
101+
}
102+
103+
double avg = sum / (double) count;
104+
for (int i = 0; i < n; i++) {
105+
for (int j = 0; j < m; j++) {
106+
if (map[i][j] == 0) {
107+
continue;
108+
}
109+
if (map[i][j] > avg) {
110+
map[i][j]--;
111+
} else if (map[i][j] < avg) {
112+
map[i][j]++;
113+
}
114+
}
115+
}
116+
}
117+
118+
public static boolean bfs(boolean[][] visited, Node startNode) {
119+
Queue<Node> que = new LinkedList<>();
120+
que.offer(startNode);
121+
visited[startNode.r][startNode.c] = true;
122+
123+
int targetNumber = map[startNode.r][startNode.c];
124+
map[startNode.r][startNode.c] = 0;
125+
int count = 1;
126+
while (!que.isEmpty()) {
127+
Node curNode = que.poll();
128+
129+
for (int i = 0; i < 4; i++) {
130+
int nextR = curNode.r + rows[i];
131+
int nextC = (curNode.c + cols[i] + m) % m;
132+
133+
if (nextR < 0 || nextR >= n) {
134+
continue;
135+
}
136+
if (!visited[nextR][nextC] && map[nextR][nextC] == targetNumber) {
137+
count++;
138+
visited[nextR][nextC] = true;
139+
map[nextR][nextC] = 0;
140+
que.offer(new Node(nextR, nextC));
141+
}
142+
}
143+
}
144+
145+
if (count == 1) {
146+
map[startNode.r][startNode.c] = targetNumber;
147+
return false;
148+
}
149+
return true;
150+
}
151+
152+
public static void rotate(int x, int k) {
153+
int[] index = new int[m];
154+
for (int i = 0; i < n; i++) {
155+
if ((i + 1) % x != 0) {
156+
continue;
157+
}
158+
for (int j = 0; j < m; j++) {
159+
index[(j + k + m) % m] = map[i][j];
160+
}
161+
for (int j = 0; j < m; j++) {
162+
map[i][j] = index[j];
163+
}
164+
}
165+
}
166+
}

0 commit comments

Comments
 (0)