# 백준 : N-Queen (9663)
문제
https://www.acmicpc.net/problem/9663소스
(Github: https://github.com/wonjnlee/wallydev/blob/master/bj_9663_N-Queen)#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <cstring>
#include <list>
#include <cmath>
using namespace std;
bool moveup[30];
bool movedown[30];
bool thisrow[15];
int N;
int cnt;
void DFS(int row) {
if(row >= N) cnt++;
for(int i=0; i<N; i++) {
if((!thisrow[i]) && (!moveup[row + i] && !movedown[N - 1 + (row - i)])) {
thisrow[i] = moveup[row + i] = movedown[N - 1 + (row - i)] = true;
DFS(row + 1);
thisrow[i] = moveup[row + i] = movedown[N - 1 + (row - i)] = false;
}
}
}
int main(void)
{
cin>>N;
DFS(0);
cout<<cnt<<endl;
return 0;
}
풀이
솔직히 이 문제 굉장히 어려웠다. 사실 아직도 정확하게 이해하지 못하고 있는 것 같기도..(다시 재 풀이해보겠다. 우선 지금까지 이해한 부분을 토대로 작성해보면)
처음 내가 풀이한 방식(실제로 해결하지 못한)은
그러던 중
식으로 진행했지만 이 또한 실패 (대각선에서 너무 많은 고민거리가 생겼었다)
결국 구글을 참조해서 어떻게 다른 분들은 이 문제를 해결했는가 확인해보았는데.
굉장히 간단하게 풀었다. (그래서 이 문제의 정답률이 60%에 육박하는구나)
1. 각 row에 체스 말이 있는지 여부를 판단하는 1차원 배열 1개
2. 해당 체스 말을 기준으로 대각선 아래부분에 다른 체스말이 있는지 판단하는 1차원배열 1개
2.1. 대각선 아래라는 의미는 [0,0], [1,1], [2,2] 순의 오른쪽 아랫방향
3. 해당 체스 말을 기준으로 대각선 윗 부분에 다른 체스말이 있는지 판단하는 1차원배열 1개
3.1. 대각선 위라는 말은 [4,0], [3,1], [2,2] 순의 오른쪽 윗방향
체스말은 오직 [0,0], [1,0], [2,0] 순으로만 이동하면서
위의 1차원 배열에 주변에 있는 녀석들이 유무만 체크해준다 (굉장히 신박한 방법)
각 1차원 배열들은 N개 기준으로 2N-1개의 갯수만큼의 대각선이 존재한다.
1. 대각선 아래부분은 [y,x]일 때 N - 1 + y-x가 모두 일치
2. 대각선 윗부분은 [y,x]일 때 y+x가 모두 일치
이러한 계산방법으로 퀸의 움직일 수 있는 예상 범위를 모두 체크해주고
마지막에 백트래킹을 할 수 있도록 예상 범위를 다시 제거해주면 된다.
결론은? 다시 풀어보자.
댓글
댓글 쓰기