0. 단순 구현 + 그래프 탐색 문제
1. 주어진 l 값에 맞게, 각 칸을 회전시킨다
2. 다른 얼음과 2칸 이하로 맞닿은 칸들을 체크한다
3. 해당 칸들을 녹인다
4. 1~3 반복
5. 다 녹은 후 dfs를 실행, 가장 큰 덩어리의 크기를 찾는다
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main{
static int[][]map;
static boolean[][] chk;
static int size;
public static void main(String[] args)throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine(), " ");
int n = pint(st.nextToken());
int m = pint(st.nextToken());
size = 1<<n;
map = new int[size][size];
for (int i = 0; i < size; i++) {
st = new StringTokenizer(br.readLine());
for (int j = 0; j < size; j++) {
map[i][j]=pint(st.nextToken());
}
}
st = new StringTokenizer(br.readLine());
for (int i = 0; i < m; i++) {
int l = pint(st.nextToken());
chk=new boolean[size][size];
//돌리기
divide(l);
//녹일것찾기
findMelt();
//녹이기
melt();
}
//dfs search
chk=new boolean[size][size];
int cntMax=0;
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
if(!chk[i][j] && map[i][j]>0) {
cntMax = Math.max(cntMax, dfs(i,j));
}
}
}
int sum=0;
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
sum+=map[i][j];
}
}
System.out.println(sum+"\n"+cntMax);
}
static int dfs(int x, int y) {
int cnt=1;
chk[x][y]=true;
if(x>0 && !chk[x-1][y] && map[x-1][y]>0)cnt+=dfs(x-1,y);
if(y>0 && !chk[x][y-1] && map[x][y-1]>0)cnt+=dfs(x,y-1);
if(x<size-1 && !chk[x+1][y] && map[x+1][y]>0)cnt+=dfs(x+1,y);
if(y<size-1 && !chk[x][y+1] && map[x][y+1]>0)cnt+=dfs(x,y+1);
return cnt;
}
static void divide(int l) {
int len = size / (1<<l);
for (int i = 0; i < len; i++) {
for (int j = 0; j < len; j++) {
rotate(i*(1<<l), j*(1<<l), 1<<l);
}
}
}
static void findMelt() {
for (int x = 0; x < size; x++) {
for (int y = 0; y < size; y++) {
int cnt=0;
if(x>0 && map[x-1][y]>0)cnt++;
if(y>0 && map[x][y-1]>0)cnt++;
if(x<size-1 && map[x+1][y]>0)cnt++;
if(y<size-1 && map[x][y+1]>0)cnt++;
if(cnt<3 && map[x][y]>0) {
chk[x][y]=true;
}
}
}
}
static void melt() {
for (int x = 0; x < size; x++) {
for (int y = 0; y < size; y++) {
if(chk[x][y])map[x][y]--;
}
}
}
static void rotate(int sx, int sy, int len) {
if(len<=0)return;
int tmp=len-1;
int[] backup = new int[tmp];
for (int i = 0; i < tmp; i++)backup[i]=map[sx][sy+i];
for (int i = 0; i < tmp; i++) {
map[sx][sy+tmp-1-i]=map[sx+i+1][sy];
}
for (int i = 0; i < tmp; i++) {
map[sx+i+1][sy]=map[sx+tmp][sy+i+1];
}
for (int i = 0; i < tmp; i++) {
map[sx+tmp][sy+i+1]=map[sx+tmp-1-i][sy+tmp];
}
for (int i = 0; i < tmp; i++) {
map[sx+tmp-1-i][sy+tmp]=backup[tmp-1-i];
}
rotate(sx+1,sy+1,len-2);
}
static int pint(String s) {
return Integer.parseInt(s);
}
}
'알고리즘 문제 풀이 > BOJ 골드' 카테고리의 다른 글
[백준] 16973 - 직사각형 탈출 (0) | 2021.11.04 |
---|---|
[백준] 23288 - 주사위 굴리기 2 (0) | 2021.11.03 |
[백준] 19236 - 청소년 상어 (0) | 2021.11.03 |
[백준] 21610 - 마법사 상어와 비바라기 (0) | 2021.10.25 |
[백준] 1339 - 단어수학 (0) | 2021.10.10 |
[백준] 14938 - 서강그라운드 (0) | 2021.10.03 |
[백준] 14891 - 톱니바퀴 (0) | 2021.09.27 |