백준/DFS and 백트래킹

[백준 9663] N-Queen

mintuchel 2024. 1. 21. 16:11

유명한 nqueen 문제이다.

그냥 백트래킹으로 풀었는데 시간초과나서 틀뜰줄 알았던게 간신히 통과가 되었다

 

근데 이 풀이는 좋은 풀이가 아니다.

nqueen 중 시간이 넉넉한 문제를 풀어서 그렇지 

더 빠른 정해들이 있다.

 

더 빠른 정해는 마지막 코드임.

 


#include <iostream>
#include <vector>
#include <cmath>

using namespace std;

int N;
int cnt;

void backtrack(int y, vector<pair<int, int>> queens) {

	if (y != queens.size()) return;

	if (y == N) {
		cnt++;
		return;
	}

	for (int x = 0; x < N; x++) {
		int flag = 1;
		// 배치 가능 검사
		for (int i = 0; i < queens.size(); i++) {
			int cury = queens[i].first;
			int curx = queens[i].second;

			// 같은 x좌표이거나 같은 기울기면
			if ((x == curx) || ((abs(y - cury) == abs(x - curx)))) {
				flag = 0;
				break;
			}
		}

		if (flag) {
			queens.push_back(make_pair(y, x));
			backtrack(y + 1, queens);
			queens.pop_back();
		}
	}
}

int main() {
	ios::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);

	cin >> N;

	vector<pair<int, int>> queens;
	backtrack(0, queens);

	cout << cnt;
	return 0;
}

 

이건 y=x+k y=-x-N+k 를 사용함

무조건 퀸은 기울기가 +-1인 대각선으로 움직일 수 있으니

해당 조건으로 풀이가 가능

 

#include <iostream>
#include <bitset>

using namespace std;

int N;
int cnt;

bitset<31> x;
bitset<31> positive_slope;
bitset<31> negative_slope;

void backtrack(int y) {
	if (y == N) {
		cnt++;
		return;
	}
	
	for (int curx = 0; curx < N; curx++) {
		if (!x[curx] && !positive_slope[curx + y] && !negative_slope[curx - y + N - 1]) {
			x[curx] = 1;
			positive_slope[curx + y] = 1;
			negative_slope[curx - y + N - 1] = 1;

			backtrack(y + 1);

			x[curx] = 0;
			positive_slope[curx + y] = 0;
			negative_slope[curx - y + N - 1] = 0;
		}
	}
}

int main() {
	ios::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);

	cin >> N;

	backtrack(0);

	cout << cnt;
	return 0;
}