ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 2667 단지번호 붙이기
    카테고리 없음 2021. 10. 27. 13:32

     

    입력 받은 값을

    stringTokenizer st = new StringTokenizer(br.readLine(), "");

    이런식으로 분리해서 0,1,0,1 이런식으로 토큰 분리하려고 했는데

    stringTokenizer는 이렇게 구분자 없이는 분리가 불가능? 한 듯 해서.....

     

     

    그래서 map[i][j]= Integer.parseInt(String.valueOf(s.charAt(j)));

    이렇게 해결

    참고

    https://velog.io/@yanghl98/%EB%B0%B1%EC%A4%80-2667-%EB%8B%A8%EC%A7%80%EB%B2%88%ED%98%B8%EB%B6%99%EC%9D%B4%EA%B8%B0-JAVA%EC%9E%90%EB%B0%94

     

    [백준] 2667 : 단지번호붙이기 (JAVA/자바)

    BOJ 2667 : 단지번호붙이기 - https://www.acmicpc.net/problem/2667모든 칸을 확인하는데, 집이 있으나 단지 번호가 아직 부여되지 않은 경우(==값은 1이고 visited되지 않은 경우) BFS탐색으로 인접한 집들에 단

    velog.io

     

    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.util.Arrays;
    import java.util.LinkedList;
    import java.util.Queue;
    
    
    
    
    class position{
    	int x;
    	int y;
    	position(int x, int y) {
    		this.x = x;
    		this.y= y;
    	}
    }
    
    
    public class Main {
    
    	
    	
    	  public static void main(String[] args) throws IOException {
    
    		  BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    		  int N = Integer.parseInt(br.readLine());
    		  int map [][]= new int [N][N];
    		  
    		  
    		  for(int i= 0; i<N;i++) {
    			String s = br.readLine();
    			  for(int j=0; j<N;j++) {
    				  map[i][j]= Integer.parseInt(String.valueOf(s.charAt(j)));
    			  }
    		  }
    		  boolean visit[][]= new boolean [N][N];
    		  StringBuilder sb = new StringBuilder();
    		  for(int i= 0; i<N;i++) {
    			  for(int j=0; j<N;j++) {
    				  if(map[i][j]==1 && !visit[i][j]) {
    					  int count = dfs(i,j,N,map,visit);
    					  sb.append(count);
    				  }
    				  
    			  }
    		  }
    		  
    		
    		  String result[] = sb.toString().split("");
    		  Arrays.sort(result);
    		  
    		  System.out.println(result.length);
    		  for(String a : result) {
    			  System.out.println(a);
    			  
    		  }
    		  
    	  }
    	  
    	  
    	  
    	  public static int dfs(int i, int j,int N, int map[][],boolean visit[][]) {
    		  
    		  Queue<position> queue = new LinkedList<>();
    		  queue.add(new position(i,j));
    		
    		  
    		  visit[i][j]=true;
    		  
    		  int count =1;
    		  while(!queue.isEmpty()) {
    			
    			  position a = queue.remove();
    			  
    			  int dx[]= {-1,1,0,0};
    			  int dy[]= {0,0,-1,1};
    			  
    			  for(int k=0; k<4;k++) {
    			  int x = a.x+dx[k];
    			  int y = a.y+dy[k];
    			  if(x>=0 && y>=0 && x<N && y<N ) {
    				  if(!visit[x][y]&&map[x][y]==1) {
    			queue.add(new position(x,y));
    			visit[x][y]=true;
    				
    				count++;
    				  }
    			  }
    		  }
    		  
    			  
    			  
    		  }
    		  
    		 
    		  
    		  
    	  return count;
    	  }
    	  
    		}

     

    이렇게 구현하니 뭔가 sts ide에서는 잘돌아가는데, 백준에 정답제출하니 틀렸다고 했다.

    왜 그러나 생각해보니, dfs는 큐가 아니라 스택이나 재귀함수로 구현한다 ㅠ

    기본적인 것을 생각하지 않고 코드를 짜서 실패했다.

     

    그래서 스택이나 재귀로 다시 구현

     

    <최종 완성본>

     

     

    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.util.ArrayList;
    import java.util.Collections;
    
    
    public class Main {
    
    	static int count;
    	
    	  public static void main(String[] args) throws IOException {
    
    		  BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    		  int N = Integer.parseInt(br.readLine());
    		  int map [][]= new int [N][N];
    		  
    		  
    		  for(int i= 0; i<N;i++) {
    			String s = br.readLine();
    			  for(int j=0; j<N;j++) {
    				  map[i][j]= Integer.parseInt(String.valueOf(s.charAt(j)));
    			  }
    		  }
    		
    		  boolean visit[][]= new boolean [N][N];
    		  ArrayList<Integer> result = new ArrayList<>();
    		  
    		  
    		  for(int i= 0; i<N;i++) {
    			  for(int j=0; j<N;j++) {
    				  if(map[i][j]==1 && !visit[i][j]) {
    					  count = 1;
    					  dfs(i,j,N,map,visit);
    					  result.add(count);
    				  }
    				  
    			  }
    		  }
    		  Collections.sort(result);
    		  
    		  System.out.println(result.size());
    		  for(int a : result) {
    			  System.out.println(a);
    			  
    		  }
    		  
    	  }
    	  
    	  
    	  
    	  public static int dfs(int i, int j,int N, int map[][],boolean visit[][]) {
    		  
    	
    		  visit[i][j]=true;
    	
    		      int dx[]= {-1,1,0,0};
    			  int dy[]= {0,0,-1,1};
    			  
    			  for(int k=0; k<4;k++) {
    			  int x = i+dx[k];
    			  int y = j+dy[k];
    			  if(x>=0 && y>=0 && x<N && y<N ) {
    				  if(!visit[x][y]&&map[x][y]==1) {
    					
    				dfs(x,y,N,map,visit);
    				  count++;
    				  }
    			  }
    			  
    		  }
    
    			  return count;
    
    	  }
    	  
    		}

     

     

     

     

     

     

    주의할점 :

     

    1)

    원래는 StringBuilder를 사용해서 count값을 출력하려고 했었다.

     

              StringBuilder sb = new StringBuilder();
    		  
    		  
    		  for(int i= 0; i<N;i++) {
    			  for(int j=0; j<N;j++) {
    				  if(map[i][j]==1 && !visit[i][j]) {
    					  count = 1;
    					  dfs(i,j,N,map,visit);
    					  sb.append(count);
    				  }
    				  
    			  }
    		  }
    		  String result [] = sb.toString().split("");
    		  Arrays.sort(result);
    		  System.out.println(result.length);
    		  for(String a : result) {
    			  System.out.println(a);
    			  
    		  }
    		  
    	  }

     

    이렇게 arraylist를 사용하지 않고 StringBuilder로 dfs 한 후의 count값을 받아서 그 결과를 출력하려고 했는데,

    이 경우 String을 Arrays.sort하는데,

    여기서 count값들은 7,8,9로 String이 아니라 int값이라 그런지

    백준에 제출했을 때 오류가 났다.

     

    그래서 참고자료를 참고해서 저렇게 ArrayList로 받으니깐 정답을 만들 수 있었다.

     

     

    2)

    그리고 count를 static 변수로 하지 않고, dfs(count)를 집어넣어서 main 메소드에서 dfs 메소드로 전달해주려고 했다.

    그런데 결과값이 이상하게 나왔다.

     

    		  
    		  int count;
    		  for(int i= 0; i<N;i++) {
    			  for(int j=0; j<N;j++) {
    				  if(map[i][j]==1 && !visit[i][j]) {
    					  count = 1;
    					  count = dfs(i,j,N,map,visit,count);
    					  result.add(count);
    				  }
    				  
    			  }
    		  }
    		  Collections.sort(result);
    		  
    		  System.out.println(result.size());
    		  for(int a : result) {
    			  System.out.println(a);
    			  
    		  }
    		  
    	  }
    	  
    	  
    	  
    	  public static int dfs(int i, int j,int N, int map[][],boolean visit[][],int count) {
    		  
    	
    		  visit[i][j]=true;
    	
    		      int dx[]= {-1,1,0,0};
    			  int dy[]= {0,0,-1,1};
    			  
    			  for(int k=0; k<4;k++) {
    			  int x = i+dx[k];
    			  int y = j+dy[k];
    			  if(x>=0 && y>=0 && x<N && y<N ) {
    				  if(!visit[x][y]&&map[x][y]==1) {
    					  count++;
    				dfs(x,y,N,map,visit,count);
    				
    				  }
    			  }
    			 
    		  }
    			 
    			  return count;
    
    	  }
    	  
    		}

     

    이렇게 dfs에다가 count변수를 넘겨주는 거로 했더니

    결과가

     

    이렇게 2 2 2 가 나왔다.

     

    그래서 System.out.println()을 사용해서 count값을 찍어봤더니

     

    	  public static int dfs(int i, int j,int N, int map[][],boolean visit[][],int count) {
    		  ***********************
    		  System.out.println(count);
              ***********************
    
    		  visit[i][j]=true;
    	
    		      int dx[]= {-1,1,0,0};
    			  int dy[]= {0,0,-1,1};
    			  
    			  for(int k=0; k<4;k++) {
    			  int x = i+dx[k];
    			  int y = j+dy[k];
    			  if(x>=0 && y>=0 && x<N && y<N ) {
    				  if(!visit[x][y]&&map[x][y]==1) {
    					  count++;
    				dfs(x,y,N,map,visit,count);
    				
    				  }
    			  }
    			 
    		  }
    			 
    			  return count;

     

    1

    2

    3

    4

    5

    6

    7

    1

    2

    3

    4

    5

    6

    7

    8

    1

    2

    3

    4

    5

    6

    7

    8

    9

    3

    2

    2

    2

    이렇게 결과값이 나왔다

     

    뭔가 7 8 9 가 나오긴 하는 것 같은데 얘네가 어디로 가는건지,

     

      public static int dfs(int i, int j,int N, int map[][],boolean visit[][],int count) {
    		  
    		  System.out.println(count);
    		  visit[i][j]=true;
    	
    		      int dx[]= {-1,1,0,0};
    			  int dy[]= {0,0,-1,1};
    			  
    			  for(int k=0; k<4;k++) {
    			  int x = i+dx[k];
    			  int y = j+dy[k];
    			  if(x>=0 && y>=0 && x<N && y<N ) {
    				  if(!visit[x][y]&&map[x][y]==1) {
    					  count++;
    				dfs(x,y,N,map,visit,count);
    				
    				  }
    			  }
    			 
    		  }
                *****************************
    			 System.out.println("언제");
                **************************
    			  return count;

     

    그래서 이렇게 count값을 return언제하나 확인해보려고 "언제" 라는 글자를 출력해보았더니

     

    1

    2

    3

    4

    언제

    5

    6

    7

    언제

    언제

    언제

    언제

    언제

    언제

    1

    2

    3

    4

    5

    6

    7

    8

    언제

    언제

    언제

    언제

    언제

    언제

    언제

    언제

    1

    2

    3

    4

    5

    6

    7

    언제

    8

    9

    언제

    언제

    언제

    언제

    언제

    언제

    언제

    언제

    3

    2

    2

    2

     

    이렇게 결과값이 나왔다.

    dfs가 아무래도 4가지 방향으로 계속 확인하다보니, 이런 결과가 나온 것 같은데,

    아직 내가 실력 부족인 듯 하여,

    다음 번에 더 알아보도록 하겠다.

     

     

    참고 자료 :

     

    https://yongku.tistory.com/entry/%EB%B0%B1%EC%A4%80-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EB%B0%B1%EC%A4%80-2667%EB%B2%88-%EB%8B%A8%EC%A7%80%EB%B2%88%ED%98%B8%EB%B6%99%EC%9D%B4%EA%B8%B0-%EC%9E%90%EB%B0%94Java

     

    [백준 알고리즘] 백준 2667번 단지번호붙이기 자바(Java)

    츄르사려고 코딩하는 코집사입니다. 1. [백준 알고리즘] 백준 2667번 단지번호붙이기 자바(Java) 1) 문제번호 : 2667번 2) 문제 출처 www.acmicpc.net/problem/2667 과 같이 정사각형 모양의 지도가 있다. 1..

    yongku.tistory.com

     

    댓글

Designed by Tistory.