그리고 문제에 두 개의 예시가 있는데 두번째 예시는 다음과 같다.. 입력으로 안 주어졌길래
8 9
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 1 1 0 0 0 1 1 0
0 1 0 1 1 1 0 1 0
0 1 0 0 1 0 0 1 0
0 1 0 1 1 1 0 1 0
0 1 1 0 0 0 1 1 0
0 0 0 0 0 0 0 0 0
//3
(1:30......... 가장 큰 문제점은...... dfs를 잘못 구현했다는 것이다. next colun, next row를 구할 때는, current r + (r방향이동) , current c+(c방향 이동) 이거여야 하는데 또, next c= nextc + (c방향 이동) 이러고 있었다 )
visit처리가 중요하다.
먼저 외부 비어있는공간들을 모두 탐색해둔다. visit처리를 해 두는 이유는, 치즈내부의 0인공간과의 비교를 위해서다
제출한 사람중 내가 젤 시간 많이 걸리는듯
import java.io.*;
import java.util.*;
public class Main {
public static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
public static StringTokenizer st;
public static int n,m;
public static int time=0;
public static int[][] board;
public static int[][] copy;
public static boolean[][] visit;
public static int[][] dirs = new int[][]{{0,1},{0,-1},{1,0},{-1,0}};
public static void setting() throws IOException{
st = new StringTokenizer(br.readLine());
n = Integer.parseInt(st.nextToken());
m = Integer.parseInt(st.nextToken());
board = new int[n][m];
copy = new int[n][m];
visit = new boolean[n][m];
for(int r=0;r<n;r++){
st = new StringTokenizer(br.readLine());
for(int c=0;c<m;c++){
board[r][c]=Integer.parseInt(st.nextToken());
}
}
}
public static void solve(){
// 먼저 전체 탐색 한 번 -> 치즈가 없으면 0이니까
if(!nocheese()){
time=0;
return;
}
int r=0,c=0,cnt=0,dir=0,nr=0,nc=0;
while(true){
// copy board into copy array && initiate visit array
for(int cr=0;cr<n;cr++){
Arrays.fill(visit[cr],false);
for(int cc=0;cc<m;cc++)
copy[cr][cc]=board[cr][cc];
}
// 가장자리에서부터 탐색 : (0,0)에서 시작하면 됨.
dfs(0,0);
// 전체를 탐색한다. -> 치즈 내부 비어있는 공간은 1로 만든다
for(r=0;r<n;r++){
for(c=0;c<m;c++) {
// 방문한 곳은 pass
if (visit[r][c]) continue;
// 0 인 공간 있나?
if (copy[r][c] == 1) continue;
copy[r][c] = 1;
visit[r][c]=true;
}
}
// 전체를 탐색한다.
for(r=0;r<n;r++){
for(c=0;c<m;c++){
if(visit[r][c])continue;
cnt=0;
// 1인 곳만을 visit하지 않게 되었음 -> 4방향을 확인
for(dir=0;dir<dirs.length;dir++){
nr = r+dirs[dir][0];
nc = c+dirs[dir][1];
if(copy[nr][nc]==1)cnt++;
}
if(cnt<=2)board[r][c]=0; //녹아보림 ..
}
}
time++;
// 치즈 있을까?
if(!nocheese())break;
}
}
public static boolean nocheese(){
for(int r=0;r<n;r++){
for(int c=0;c<m;c++){
if(board[r][c]==1)return true;
}
}
return false;
}
// dfs
public static void dfs(int sr,int sc){
visit[sr][sc]=true;
int nr=sr,nc=sc;
for(int dir=0;dir<dirs.length;dir++){
nr = sr+dirs[dir][0];
nc = sc+dirs[dir][1];
if(nr<0||nc<0||nr>=n||nc>=m)continue;
if(visit[nr][nc] ||copy[nr][nc]==1)continue;
dfs(nr,nc);
}
}
public static void main(String[] args)throws IOException {
setting();
solve();
System.out.println(time);
}
}
import java.io.*;
import java.util.*;
public class Main {
public static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
public static StringTokenizer st;
public static int n,m;
public static int time=0;
public static int[][] board;
public static int[][] copy;
public static boolean[][] visit;
public static int[][] dirs = new int[][]{{0,1},{0,-1},{1,0},{-1,0}};
public static void setting() throws IOException{
st = new StringTokenizer(br.readLine());
n = Integer.parseInt(st.nextToken());
m = Integer.parseInt(st.nextToken());
board = new int[n][m];
copy = new int[n][m];
visit = new boolean[n][m];
for(int r=0;r<n;r++){
st = new StringTokenizer(br.readLine());
for(int c=0;c<m;c++){
board[r][c]=Integer.parseInt(st.nextToken());
}
}
}
public static void solve(){
// 먼저 전체 탐색 한 번 -> 치즈가 없으면 0이니까
if(!nocheese()){
time=0;
return;
}
int r=0,c=0,cnt=0,dir=0,nr=0,nc=0;
// 가장자리에서부터 탐색 : (0,0)에서 시작하면 됨.
dfs(0,0);
// while문을 반복하며 가장자리의 것들이 녹아내린다
while(true){
// copy board into copy array && initiate visit array
for(int cr=0;cr<n;cr++){
for(int cc=0;cc<m;cc++)
copy[cr][cc]=board[cr][cc];
}
// 전체를 탐색한다. -> 치즈 내부 비어있는 공간은 1로 만든다
for(r=0;r<n;r++){
for(c=0;c<m;c++) {
// 방문한 곳은 pass
if (visit[r][c]) continue;
// 0 인 공간 있나?
if (copy[r][c] == 1) continue;
copy[r][c] = 1;
}
}
// 전체를 탐색한다.
for(r=0;r<n;r++){
for(c=0;c<m;c++){
if(visit[r][c])continue;
cnt=0;
// 1인 곳만을 visit하지 않게 되었음 -> 4방향을 확인
for(dir=0;dir<dirs.length;dir++){
nr = r+dirs[dir][0];
nc = c+dirs[dir][1];
if(copy[nr][nc]==1)cnt++;
}
if(cnt<=2){
board[r][c]=0; //녹아보림 ..
dfs(r,c); // 녹음으로서 내부공간이 노출 --> 여기서부터 dfs를 해주도록
}
}
}
time++;
// 치즈 있을까? -> 더 없으면 break;
if(!nocheese())break;
}
}
public static boolean nocheese(){
for(int r=0;r<n;r++){
for(int c=0;c<m;c++){
if(board[r][c]==1)return true;
}
}
return false;
}
// dfs
public static void dfs(int sr,int sc){
visit[sr][sc]=true;
int nr=sr,nc=sc;
for(int dir=0;dir<dirs.length;dir++){
nr = sr+dirs[dir][0];
nc = sc+dirs[dir][1];
if(nr<0||nc<0||nr>=n||nc>=m)continue;
if(visit[nr][nc] ||board[nr][nc]==1)continue;
dfs(nr,nc);
}
}
public static void main(String[] args)throws IOException {
setting();
solve();
System.out.println(time);
}
}
대충 효율이 이렇게 변했다