MoveCrashingWall_answer2

대박적, 환상적

  • 방문 체크 확실히!

순회할 때 방문 체크 자꾸 깜빡한다! 방문하기 전에 visit[nx][ny] = true인지(이미 방문한 노드인지) 방문체크 안 해준다거나! 방문하고 나서 visit[nx][ny] = true로 안 바꿔준다거나

다른 사람들의 코드를 몇개 봤는데 일관된 공통점이 있었다. 클래스를 만들 때, x,y,drill_cnt 뿐만 아니라 dist도 생성하여 값을 함께 저장해주었다!

반복 체크하는 건 단순 boolean 배열 객체 visit만으로 해주어서, int 배열로 만들었을 때보다 중의적인 의미가 없어서 직관적 이해가 쉬웠다!

  • 문제의 핵심

벽 부수는 횟수(crashCnt)가 0일 때 1일 때 탐색 처리해주는 부분이다. 같은 (x,y) 좌표에 대해서 crashCnt=0일 때, crashCnt=1일 때 (x,y)는 다른 좌표이기 때문에 다르게 처리해주어야한다!

  1. 이미 벽을 한번 부쉈을 때 : visit[1]차원에 대해 처리해준다! 큐에 다음 좌표 객체를 생성해서 넣어줄 때도 crashCnt 값을 1로 해서 넣어준다! 진짜 신박하고 짜릿짜릿해.

if(cur.crashCnt==1){//그래도 탐색은 계속되어야하니까.
    //다음 노드 nx,ny에 대해서도 visit[1]차원으로 탐색이 진행되어야 한다.
    if(map[nx][ny] == '1' || visit[1][nx][ny]) continue;
    //큐에 객체 생성해서 넣을 때도 crashCnt = 1로 해준다.
    q.add(new Wall(nx,ny,cur.dist+1,1));
    visit[1][nx][ny] = true;
}

2. 아직 벽을 부수지 않았을 때 큐에 넣는 다음 좌표 객체의 crashCnt는 map[nx][ny]값에 따라 1이면 벽을 부술 거기 때문에 crashCnt 또한 1이 되고, map[nx][ny]가 0이면 crashCnt 또한 0이 된다!

else{//아직 벽 부수지 않았을 때
    if(visit[0][nx][ny]) continue;
    q.add(new Wall(nx,ny,cur.dist+1,map[nx][ny]-'0'));
    visit[map[nx][ny]-'0'][nx][ny] = true;
}
  • 리팩토링 입력 1. String[ ] 대신 StringTokenizer 이용 String input[ ] = br.readLine().split(" "); 처럼 사용하면 된다!

StringTokenizer st = new StringTokenizer(br.readLine()," ");
n = Integer.parseInt(st.nextToken());
m = Integer.parseInt(st.nextToken());

2. 공백없는 정수형 배열 => 정수 변환하지 않고 그대로 toCharArray()로 저장 br.readLine()이 String을 반환하니까 이 String 값을 그대로 char형 배열로 저장한다.

for(int i=0;i<n;i++) {
    map[i] = br.readLine().toCharArray();
}

3. 범위체크 함수 구현 및 함수 private으로 선언해도 시간이 좀 감소한다!

Last updated