사용한 것
- 이다솜파와 임도연파를 선택하기 위한 DFS
- 선택한 7명이 인접했는지 확인하기 위한 BFS
풀이 방법
- 우선 DFS로 이다솜파를 선택한다.
- 선택 X or 선택 O 분기처리를 사용한다.
- 이다솜파가 4명 이상 선택됐으면 임도연파를 선택한다.
- 이다솜파를 선택하지 않았는데
setY()
를 호출하면 중복될 수 있으므로 flag
를 사용한다.
- 이다솜파 선택 후 임도연파를 선택한다.
- 7명 모두 선택됐으면 BFS로 모두 인접했는지 확인한다.
코드
public class Main {
private static final int[] DX = {-1, 0, 1, 0};
private static final int[] DY = {0, 1, 0, -1};
private static final int N = 5;
private static final int SIZE = 7;
private static char[] map = new char[N * N];
private static Set<Integer> set = new HashSet<>();
private static int sCount = 0;
private static int answer = 0;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String line;
for (int i = 0; i < N; i++) {
line = br.readLine();
for (int j = 0; j < N; j++) {
map[N * i + j] = line.charAt(j);
}
}
findAnswer();
System.out.println(answer);
}
private static void findAnswer() {
setS(0, 0, false);
}
private static void setS(int depth, int idx, boolean flag) {
if (flag && sCount > SIZE / 2) {
setY(depth, 0);
}
if (depth == SIZE || idx == N * N) {
return;
}
setS(depth, idx + 1, false);
if (map[idx] == 'S') {
set.add(idx);
sCount++;
setS(depth + 1, idx + 1, true);
set.remove(idx);
sCount--;
}
}
private static void setY(int depth, int idx) {
if (depth == SIZE) {
if (check()) {
answer++;
}
return;
}
if (idx == N * N) {
return;
}
setY(depth, idx + 1);
if (map[idx] == 'Y') {
set.add(idx);
setY(depth + 1, idx + 1);
set.remove(idx);
}
}
private static boolean check() {
for (int i = 0; i < N * N; i++) {
if (set.contains(i)) {
int initX = i / N;
int initY = i % N;
Queue<int[]> q = new LinkedList<>();
boolean[][] visited = new boolean[N][N];
q.offer(new int[]{initX, initY});
visited[initX][initY] = true;
int ct = 0;
while (!q.isEmpty()) {
int[] cp = q.poll();
int cx = cp[0];
int cy = cp[1];
ct++;
for (int j = 0; j < 4; j++) {
int nx = cx + DX[j];
int ny = cy + DY[j];
if (isOOB(nx, ny) || visited[nx][ny]) {
continue;
}
if (set.contains(N * nx + ny)) {
q.offer(new int[]{nx, ny});
visited[nx][ny] = true;
}
}
}
if (ct == SIZE) {
return true;
}
break;
}
}
return false;
}
private static boolean isOOB(int x, int y) {
if (x < 0 || x >= N || y < 0 || y >= N) {
return true;
}
return false;
}
}