Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 33b6ec6

Browse files
committed
이예진: [CT] 색깔 폭탄_241209
1 parent aef4beb commit 33b6ec6

File tree

1 file changed

+214
-0
lines changed

1 file changed

+214
-0
lines changed
Lines changed: 214 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,214 @@
1+
import java.io.BufferedReader;
2+
import java.io.IOException;
3+
import java.io.InputStreamReader;
4+
import java.util.ArrayDeque;
5+
import java.util.ArrayList;
6+
import java.util.Collections;
7+
import java.util.Deque;
8+
import java.util.List;
9+
import java.util.StringTokenizer;
10+
11+
public class YJ_색깔_폭탄 {
12+
static class Bundle implements Comparable<Bundle>{
13+
List<int[]> bombs;
14+
int red;
15+
int rows;
16+
int columns;
17+
18+
Bundle(List<int[]> bombs, int red, int rows, int columns){
19+
this.bombs = bombs;
20+
this.red = red;
21+
this.rows = rows;
22+
this.columns = columns;
23+
}
24+
25+
@Override
26+
public int compareTo(Bundle b){
27+
if(this.bombs.size() == b.bombs.size()){
28+
if(this.red == b.red){
29+
if(this.rows == b.rows){
30+
//3. 가장 열이 작은 폭탄 묶음
31+
return this.columns - b.columns;
32+
}
33+
//2. 행이 가장 큰 폭탄 묶음 (행이 빨간색이 아니면서 가장 큰 칸)
34+
return b.rows - this.rows;
35+
}
36+
//1. 빨간색 폭탄이 가장 적은 묶음
37+
return this.red - b.red;
38+
}
39+
//사이즈가 가장 큰 순서
40+
return b.bombs.size() - this.bombs.size();
41+
}
42+
}
43+
44+
static int n;
45+
static int m;
46+
static int[][] bombs;
47+
static List<Bundle> bundles = new ArrayList<>(); //묶음 폭탄 저장소
48+
static final int BLACK = -1;
49+
static final int RED = 0;
50+
static final int NULL = -2;
51+
52+
public static void main(String[] args) throws IOException {
53+
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
54+
String[] data = br.readLine().split("\\s");
55+
n = Integer.parseInt(data[0]);
56+
m = Integer.parseInt(data[1]);
57+
bombs = new int[n][n];
58+
59+
for(int i=0; i<n; i++){
60+
StringTokenizer st = new StringTokenizer(br.readLine());
61+
for(int j=0; j<n; j++){
62+
bombs[i][j] = Integer.parseInt(st.nextToken());
63+
}
64+
}
65+
66+
int score = 0;
67+
do{
68+
find();
69+
if(bundles.isEmpty()){
70+
break;
71+
}
72+
73+
Bundle bombBundle = bundles.get(0);
74+
if(bundles.size() > 1){
75+
bombBundle = filter();
76+
}
77+
78+
score += remove(bombBundle);
79+
move();
80+
81+
bundles.clear();
82+
}while(true);
83+
84+
System.out.println(score);
85+
}
86+
87+
//가장 큰 폭탄 묶음 찾기 (연결되어있어야함)
88+
static void find(){
89+
for(int i=0; i<n; i++){
90+
for(int j=0; j<n; j++){
91+
if(!stop(i,j)){
92+
bfs(i,j);
93+
}
94+
}
95+
}
96+
}
97+
98+
static int[] nx = {1,0,-1,0};
99+
static int[] ny = {0,1,0,-1};
100+
static boolean[][] visited;
101+
private static void bfs(int x, int y){
102+
Deque<int[]> deque = new ArrayDeque<>();
103+
visited = new boolean[n][n];
104+
105+
deque.offer(new int[]{x,y});
106+
visited[x][y] = true;
107+
int color = bombs[x][y];
108+
109+
//폭탄 묶음 초기화
110+
List<int[]> bombList = new ArrayList<>();
111+
bombList.add(new int[]{x,y});
112+
int red = color == RED? 1 : 0;
113+
int rows = x;
114+
int columns = y;
115+
116+
while(!deque.isEmpty()) {
117+
int[] current = deque.poll();
118+
for (int d = 0; d < 4; d++) {
119+
int dx = current[0] + nx[d];
120+
int dy = current[1] + ny[d];
121+
122+
if (stop(dx, dy) || visited[dx][dy]) {
123+
continue;
124+
}
125+
126+
int bomb = bombs[dx][dy];
127+
//빨간색 폭탄 또는 한가지색 만 올 수 있음
128+
if(bomb == color || bomb == RED){
129+
if(bomb == RED){
130+
red++;
131+
}
132+
//빨간색이 아니면서 가장 행이 큰 폭탄 묶음
133+
if(dx > rows && bomb != RED){
134+
rows = dx;
135+
}
136+
//가장 작은 열
137+
if(dy < columns){
138+
columns = dy;
139+
}
140+
141+
deque.offer(new int[]{dx,dy});
142+
bombList.add(new int[]{dx,dy});
143+
visited[dx][dy] = true;
144+
}
145+
}
146+
}
147+
148+
//폭탄 묶음이란 2개 이상의 폭탄으로 구성
149+
if(bombList.size() > 1){
150+
bundles.add(new Bundle(bombList,red,rows,columns));
151+
}
152+
}
153+
154+
private static boolean stop(int x, int y){
155+
return x < 0 || y < 0 || x >= n || y >= n || bombs[x][y] == BLACK || bombs[x][y] == NULL;
156+
}
157+
158+
//동일한 폭탄묶음 필터링
159+
static Bundle filter(){
160+
Collections.sort(bundles);
161+
return bundles.get(0);
162+
}
163+
164+
//폭탄 묶음 제거 > 폭탄 갯수 점수 구하기(C*C)
165+
static int remove (Bundle bombBundle){
166+
//제거하려면 위치를 알아야함
167+
List<int[]> bombList = bombBundle.bombs;
168+
for(int[] pos : bombList){
169+
bombs[pos[0]][pos[1]] = NULL;
170+
}
171+
172+
int count = bombList.size();
173+
return count*count;
174+
}
175+
176+
//폭탄들 움직이기 (중력 + 반시계 방향으로 90 도 회전)
177+
static void move(){
178+
moveDown();
179+
rotate();
180+
moveDown();
181+
}
182+
183+
//중력 작용
184+
private static void moveDown(){
185+
for(int i=n-2; i>=0; i--){
186+
for(int j=0; j<n; j++){
187+
if(bombs[i][j] == BLACK || bombs[i][j] == NULL){
188+
continue;
189+
}
190+
//가장 끝 빈공간까지 인덱스를 이동
191+
int index = i+1;
192+
while(index < n && bombs[index][j] == NULL){
193+
index++;
194+
}
195+
//해당 인덱스 위치로 이동이 가능할 경우 while 내에서 +1 되었기 때문에 i+2 가 된 상태
196+
if(index-1 != i){
197+
bombs[index-1][j] = bombs[i][j];
198+
bombs[i][j] = NULL;
199+
}
200+
}
201+
}
202+
}
203+
204+
//반시계 방향 90도 회전
205+
private static void rotate(){
206+
int[][] temp = new int[n][n];
207+
for(int i=0; i<n; i++){
208+
for(int j=0; j<n; j++){
209+
temp[i][j] = bombs[j][n-1-i];
210+
}
211+
}
212+
bombs = temp;
213+
}
214+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /