티스토리 뷰

알고리즘

[백준] 11559. Puyo Puyo (Java)

melthleeth 2021. 7. 23. 01:00

 

 

11559번: Puyo Puyo

총 12개의 줄에 필드의 정보가 주어지며, 각 줄에는 6개의 문자가 있다. 이때 .은 빈공간이고 .이 아닌것은 각각의 색깔의 뿌요를 나타낸다. R은 빨강, G는 초록, B는 파랑, P는 보라, Y는 노랑이다.

www.acmicpc.net

 

풀이

  • 완전 시뮬레이션 문제 = method를 많이 만들어야 함
  • 처음에 뿌요 위치를 큐에 가져온다. (getPuyo()로 구현)
  • 이제 뿌요 있는곳만 터트릴 수 있는지 확인
  • 터트릴 수 있는 얘들 싹 모아서 비우고 맵 정리
  • 한 연쇄가 끝나면 정답 카운트++

 

풀기 전 의문점

위에서부터 터짐? 아래서부터 터짐?
동시에 두 개 이상 터지면 어떻게 됨?

  • 동시에 터져야 한다.
  • 여러번 터져도 연쇄는 한 번만 친다.

 

터지는 뿌요를 찾았다. 이제 이걸 어떻게 맵에서 없애지?

  1. 터트릴 후보를 큐에 넣는다. (BFS(x, y)에서 네 개 이상 덩어리면 willBePopped 큐에 넣기)
  2. map[x][y] = '.'로 바꾼다. (popPuyo()로 구현)
  3. column을 돌면서 밑으로 내린다. (arrangeMap()로 구현)
  • arrangeMap()에선 우선 .이 제일 처음으로 나온 위치를 baseline으로 설정하고 그 뒤로 뿌요가 나올때 마다 바로바로 .인 자리로 바꿔치기 해줬다.

 

코드

import java.io.*;
import java.util.*;
public class Main {
static char[][] map = new char[14][8];
static int ans;
static int[] px = new int[]{1, 0, -1, 0};
static int[] py = new int[]{0, 1, 0, -1};
static boolean[][] visited;
static Queue<Coord> puyos, willBePopped;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
for (int i = 1; i <= 12; i++){
char[] arr = br.readLine().toCharArray();
for (int j = 1; j <= 6; j++)
map[i][j] = arr[j - 1];
}
while (true) {
if (!puyoPuyo()) break;
ans++;
}
bw.write(String.valueOf(ans));
br.close();
bw.close();
}
public static boolean puyoPuyo() {
puyos = new LinkedList<>();
willBePopped = new LinkedList<>();
visited = new boolean[14][8];
getPuyo();
int size = puyos.size();
for (int i = 0; i < size; i++) {
int x = puyos.peek().x;
int y = puyos.peek().y;
puyos.poll();
if (visited[x][y]) continue;
visited[x][y] = true;
BFS(x, y);
}
if (willBePopped.isEmpty()) return false;
else {
visited = new boolean[14][8];
while(!willBePopped.isEmpty()) {
int x = willBePopped.peek().x;
int y = willBePopped.peek().y;
willBePopped.poll();
visited[x][y] = true;
popPuyo(x, y);
}
arrangeMap();
}
return true;
}
public static void arrangeMap() {
for (int j = 1; j <= 6; j++) {
for (int i = 12; i >= 1; i--) {
if (map[i][j] == '.') {
int baseLine = i;
for (int h = baseLine - 1; h >= 1; h--) {
if (map[h][j] != '.') {
map[i--][j] = map[h][j];
map[h][j] = '.';
}
}
}
}
}
}
public static void popPuyo(int x, int y) {
char color = map[x][y];
map[x][y] = '.';
Queue<Coord> q = new LinkedList<>();
q.offer(new Coord(x, y));
while(!q.isEmpty()) {
int a = q.peek().x;
int b = q.peek().y;
q.poll();
for (int d = 0; d < 4; d++) {
int nx = a + px[d];
int ny = b + py[d];
if (map[nx][ny] != color || visited[nx][ny]) continue;
visited[nx][ny] = true;
map[nx][ny] = '.';
q.offer(new Coord(nx, ny));
}
}
}
public static void BFS(int x, int y) {
int cnt = 1;
char color = map[x][y];
Queue<Coord> q = new LinkedList<>();
q.offer(new Coord(x, y));
while(!q.isEmpty()) {
int a = q.peek().x;
int b = q.peek().y;
q.poll();
for (int d = 0; d < 4; d++) {
int nx = a + px[d];
int ny = b + py[d];
if (map[nx][ny] != color || visited[nx][ny]) continue;
cnt++;
visited[nx][ny] = true;
q.offer(new Coord(nx, ny));
}
}
if (cnt >= 4) willBePopped.offer(new Coord(x, y));
}
public static void getPuyo() {
for (int i = 1; i <= 12; i++)
for (int j = 1; j <= 6; j++)
if (map[i][j] != '.') puyos.offer(new Coord(i, j));
}
static class Coord {
int x;
int y;
public Coord(int x, int y) {
this.x = x;
this.y = y;
}
}
}

 

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/08   »
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
글 보관함