알고리즘/문제풀이
[백준] Q1799 비숍 JAVA
케팔스
2022. 3. 7. 16:38
https://www.acmicpc.net/problem/1799
1799번: 비숍
첫째 줄에 체스판의 크기가 주어진다. 체스판의 크기는 10이하의 자연수이다. 둘째 줄부터 아래의 예와 같이 체스판의 각 칸에 비숍을 놓을 수 있는지 없는지에 대한 정보가 체스판 한 줄 단위로
www.acmicpc.net
1. 문제의 유형 및 이해
구현, 백트래킹
N-Queen 문제와 유사하면서도 조건이 달려있는 문제입니다.
N-Queen 문제처럼 놓을 수 있는 곳에 비숍을 놓아가면서 놓을 수 있는지 확인하면서 진행하면 됩니다.
Queen 과 달리 비숍의 경우 움직일 수 있는 상태공간은 대각선으로 특정할 수 있습니다.
다만 대각선이라 기존의 n queen 과는 다른 방법으로 가능한지 여부를 체크해 주어야 합니다.
2. 문제 접근 방법
/ 방향 : x + y 값이 같은 좌표
\ 방향 : y - x 값이 같은 좌표
/ 방향에 대해 0 ~ 2N-2 까지의 대각선을 특정할 수 있고
반대 방향에 대해 -N+1 ~ N-1까지의 대각선을 특정할 수 있습니다.
즉 어떠한 비숍을 (a,b)의 좌표에 놓았을 때 대각선 두개의 위치를 통해 해당 좌표를 특정할 수 있고 각각의 대각선에 가능한 여부를 통해 놓을 수 있는지 없는지 확인할 수 있습니다.
또한, 체스 판에 색칠되어 있는 판 모양을 잘 생각해보면 각 색칠한 구간은 서로의 비숍이 절대 닿지 못하는 곳입니다.
해당 부분을 따로 구함으로써 시간을 더욱 줄일 수 있습니다.
package solvedac.level5.gold1;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
/**
* @author : pcrmcw0486
* @문제번호 : Q1799
* @문제이름 : 비숍
* @난이도 : Gold I
* @date : 2022-02-28 오후 2:58
* @문제이해 비숍은 대각선으로 움직일 수 있다.
* 비숍이 놓일 수 없는 곳이 있다.(놓일순 없지만, 지나갈 수는 있다)
* 주어진 체스판에서 서로가 잡을 수 없는 위치에 놓을 수 있는 비숍의 최대 개수를 구하시오.
* 체스판의 크기는 10이하. (놓을 수 있다면 1 없다면 0)
* @알고리즘 10개 이하 많이 놓아봐야 2N-1개
* @접근방법
* 체스판에 왜 색칠이 되어있는지 알고 있나?
*/
public class Main {
static int N;
static char[][] map;
static boolean[] LURD;
static boolean[] RULD;
static int cnt, ans;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
N = Integer.parseInt(br.readLine());
map = new char[N][N];
LURD = new boolean[2 * N];
RULD = new boolean[2 * N];
for (int i = 0; i < N; i++) {
String line = br.readLine().replaceAll(" ","");
for (int j = 0; j < N; j++) {
map[i][j] = line.charAt(j);
}
}
ans =0;
ans = findMaxBishop(0) + findMaxBishop(1);
System.out.println(ans);
}
private static int findMaxBishop(int depth) {
if (depth >= (2 * N)-1){
return 0;
}
//대각선의 개수 depth 는 2N-1개가 있음.
// 대각선 idx가 0부터 시작하므로 2N-2까지.
int x;
int y;
int ret =-1;
//depth는 최대 2N-2 (N-1) = N-1
for (x = 0; x <= Math.min(depth, N - 1); x++) {
y = depth - x;
if(y > N-1) continue;
if (map[x][y] == '1') {
if (RULD[x + y] || LURD[y - x + N]) continue;
RULD[x + y] = LURD[y - x + N] = true;
ret = Math.max(ret, findMaxBishop(depth + 2)+1);
RULD[x + y] = LURD[y - x + N] = false;
}
}
if(ret < 0)
ret = findMaxBishop(depth + 2);
return ret;
}
}