<테스트케이스1>
2 20 50
50 30
20 40
헛점으로 기록된 부분은 오른쪽/아래로 탐색하는데 유턴해서 돌아오는경우(아래 예시)
(0,1) (0,2)
↓ ↑
(1,1)→ (1,2)
right값이나 down값으로 dfs를 엮을수 없다.
따라서 현재 좌표 위치에서
1. 왼쪽좌표의 right값이 true인지
2. 위의좌표의 down값이 true인지
를 통해서 추가로 확인해줌으로써 국경들을 모두 이을 수 있었다.
전체코드
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;
public class Main {
static People[][] map;
static boolean[][] visit;
static int N, L, R;
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken());
L = Integer.parseInt(st.nextToken());
R = Integer.parseInt(st.nextToken());
map = new People[N][N];
visit = new boolean[N][N];
for (int r = 0; r < N; r++) {
st = new StringTokenizer(br.readLine());
for (int c = 0; c < N; c++) {
map[r][c] = new People(Integer.parseInt(st.nextToken()));
}
}
while (true) {
boolean check = start();
if (check) count++;
else {
//System.out.println("break");
break;
}
}
System.out.println(count);
}
static int count = 0;
static ArrayList<Loc> list = new ArrayList<>();
static boolean start() {
//System.out.println("start");
visit = new boolean[N][N];
boolean haveMoved = false;
for (int r = 0; r < N; r++) {
for (int c = 0; c < N; c++) {
People p = map[r][c];
p.checkRight(r, c);
p.checkDown(r, c);
}
}
for (int r = 0; r < N; r++) {
for (int c = 0; c < N; c++) {
if (visit[r][c]) continue;
list.clear();
dfs(r, c);
if (list.size() > 1) {
int sum = 0;
for (int i = 0; i < list.size(); i++) {
Loc l = list.get(i);
People p = map[l.r][l.c];
sum += p.val;
}
int average = sum / list.size();
//System.out.println(average + "list size:" +list.size());
for (int i = 0; i < list.size(); i++) {//평균값으로 setVal
Loc l = list.get(i);
//System.out.println(l.r+"/" + l.c);
map[l.r][l.c].setVal(average);
map[l.r][l.c].right = false;
map[l.r][l.c].down = false;
}
haveMoved = true;
}
}
}
return haveMoved;
}
static void dfs(int r, int c) {
People p = map[r][c];
visit[r][c] = true;
list.add(new Loc(r, c));
if (p.right && !visit[r][c + 1]) {
dfs(r, c + 1);
}
if(c>=1) {
People leftP = map[r][c - 1];
if (leftP.right && !visit[r][c-1]){
dfs(r,c-1);
}
}
if (p.down && !visit[r + 1][c]) {
dfs(r + 1, c);
}
if(r>=1) {
People leftP = map[r-1][c];
if (leftP.down && !visit[r-1][c]){
dfs(r-1,c);
}
}
return;
}
static class Loc {
int r, c;
Loc(int r, int c) {
this.r = r;
this.c = c;
}
}
static class People {
int val;
boolean right = false,
down = false;
People(int val) {
this.val = val;
}
public void setVal(int val) {
this.val = val;
}
public void checkRight(int r, int c) {
if (r >= 0 && r < N && c >= 0 && c < N - 1) {
int thatVal = map[r][c + 1].val;
if (Math.abs(thatVal - this.val) >= L && Math.abs(thatVal - this.val) <= R) {
right = true;
}
}
}
public void checkDown(int r, int c) {
if (r >= 0 && r < N - 1 && c >= 0 && c < N) {
int thatVal = map[r + 1][c].val;
if (Math.abs(thatVal - this.val) >= L && Math.abs(thatVal - this.val) <= R) {
down = true;
}
}
}
}
}
반응형
'코딩테스트 > Java' 카테고리의 다른 글
(2021 카카오) 광고삽입 JAVA (0) | 2021.09.11 |
---|---|
[JAVA] 백준 주사위 윷놀이 (0) | 2021.09.01 |
[JAVA] 백준 상어초등학교 (0) | 2021.08.26 |
[JAVA] 백준 나무재테크 (0) | 2021.08.18 |
(프로그래머스) 다단계 칫솔 (0) | 2021.07.29 |