DP문제에서 막혀서 더 못풀었다 ㅠㅠ 이번에 자신있었는데..
열심히 공부해서 다음주 진단에는 600점 이상 받을 수 있도록 노력하려고한다.
https://www.codetree.ai/cote/14/problems/clear-stones-well?&utm_source=clipboard&utm_medium=text
import java.util.*;
import java.io.*;
public class Main {
static int n, m, k;
static int[] dx = {0, 0, -1, 1}; // 상하좌우 4가지 방향
static int[] dy = {1, -1, 0, 0};
static int[][] map;
static ArrayList<Pair> stoneList; // 돌 위치 기록 리스트
static ArrayList<Pair> list; // 뽑은 돌의 위치 기록 리스트
static class Pair {
int x, y;
Pair(int x, int y) {
this.x = x;
this.y = y;
}
}
static int ans = 0;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer stk = new StringTokenizer(br.readLine(), " ");
n = Integer.parseInt(stk.nextToken());
k = Integer.parseInt(stk.nextToken());
m = Integer.parseInt(stk.nextToken());
map = new int[n + 1][n + 1];
stoneList = new ArrayList<>(); // 주어진 돌의 위치 기록
for (int i = 1; i <= n; i++) {
stk = new StringTokenizer(br.readLine(), " ");
for (int j = 1; j <= n; j++) {
map[i][j] = Integer.parseInt(stk.nextToken());
if (map[i][j] == 1) {
stoneList.add(new Pair(i, j));
}
}
}
list = new ArrayList<>();
for (int i = 0; i < k; i++) {
stk = new StringTokenizer(br.readLine(), " ");
int x = Integer.parseInt(stk.nextToken());
int y = Integer.parseInt(stk.nextToken());
map[x][y] = 2; // 시작점 기록
}
backtracking(m, 0);
System.out.println(ans);
}
private static void backtracking(int m, int count) {
if (count == m) { // m개의 돌을 고른 후 탐색
// 최댓값 갱신
ans = Math.max(ans, bfs());
return;
}
for (int i = 0; i < stoneList.size(); i++) {
list.add(stoneList.get(i));
backtracking(m, count + 1);
list.remove(list.size() - 1);
}
}
private static int bfs() {
Queue<Pair> q = new LinkedList<>();
int[][] new_map = new int[n + 1][n + 1];
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
new_map[i][j] = map[i][j];
if (new_map[i][j] == 2) { // 시작위치를 큐에 삽입
q.offer(new Pair(i, j));
}
}
}
for (int i = 0; i < list.size(); i++) {
Pair cur = list.get(i); // 뽑은 돌의 위치를 new_map에서 0으로 바꿔줌(돌을 치움)
new_map[cur.x][cur.y] = 0;
}
while (!q.isEmpty()) { // 탐색
Pair cur = q.poll();
for (int dir = 0; dir < 4; dir++) {
int nx = cur.x + dx[dir];
int ny = cur.y + dy[dir];
if (nx <= 0 || ny <= 0 || nx > n || ny > n) {
continue;
}
// 방문했거나 돌이 있으면 넘어감
if (new_map[nx][ny] == 2 || new_map[nx][ny] == 1) {
continue;
}
q.offer(new Pair(nx, ny));
new_map[nx][ny] = 2; // 방문 기록
}
}
// 탐색할 수 있는 지점 세기
int count = 0;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
if (new_map[i][j] == 2) {
count++;
}
}
}
return count;
}
}
#코드트리 #코딩테스트 #코딩테스트실력진단