[๋ฐฑ์ค] [C++] ๐งฉ N-Queen (Hard) 30243๋ฒ
๐ก ๋ฌธ์ ์ค๋ช

๊ธฐ์กด์ N-Queen ๋ฌธ์ ์ ๊ฐ์ง๋ง, N<=30์ผ๋ก 30๋จ๊ณ๊น์ง ๊ฐ์ผ ํด์ ๋นํธ๋ง์คํน ์์ด๋ ์ ๋๋ก ์๊ฐ์ ํ ์์ ๋ฌธ์ ๋ฅผ ํ ์ ์๋ค.
๋ค๋ฅธ N-Queen ๋ฌธ์ ์ ๊ฐ์ด ๋ฐฑํธ๋ํน์ ์ฌ์ฉํ๋ฉด๋๋ค.
๐ก ๋ฐฑํธ๋ํน ๋ฐฉ์
๋ฐฑํธ๋ํน๊ณผ ์ ๋ฐ์ ์ธ ํ์ด ๋ฐฉ์์ ๐งฉ N-Queen (Easy) ํ์ด ์ ๋์ผํ๋ค. ์๋ดค๋ค๋ฉด ๊ผญ ๋ณด๊ณ ์ค์.
๐ก ์์ ๋นํธ์ฐ์ฐ?
์ค๊ฐ์ for๋ฌธ์์ ์ฒ์ ๋ณด๋ ๋ด์ฉ์ด ์์ ๊ฒ์ด๋ค.
bit์์ ์ตํ์ ๋นํธ๋ฅผ ํ๋์ฉ ๋ฝ์์ a๋ก ๋ํ๋ด ์งํํ๋ค.
// ์ตํ์ ๋นํธ๋ถํฐ ์์ ๋ฉด์ ๋ชจ๋ ๋นํธ๊ฐ ์์ด์ง๋๊น์ง ํ๋์ฉ ์ฌ๊ท
for(ll a=0; bit!=0; bit ^= a){
a = bit & (-bit); // bit์ ์ตํ์ ๋นํธ
์์
int bit = 0b0001100100; // bit๊ฐ 0001100100 ์ด๋ฉด
int a = bit & (-bit); // ์์ ์ ์์๊ฐ๊ณผ AND ์ฐ์ฐ์ ํ๋ฉด
cout << "bit : " << bitset<10>(bit) << endl; // 2์ง์๋ก bit ์ถ๋ ฅ
cout << "a : " << bitset<10>(a) << endl; // 2์ง์๋ก a ์ถ๋ ฅ
// ๊ฒฐ๊ณผ
// bit : 0001100100
// a : 0000000100
๐ก C++ ํ์ด
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
#define FOR(i,a,b) for(int i=(a);i<=(b);i++)
#define MAX
int N;
int row; // ๊ฐ๋ก (๋์ ์ ์๋๊ณณ์ด 1)
ll lx, rx; // ์ผ๋๊ฐ์ , ์ค๋ฅธ๋๊ฐ์ (๋์ ์ ์๋๊ณณ์ด 1)
int Q[30];
int step[30];
int ans[30];
bool backtracking(int level){
if(level>N){
return true;
}
// bit : ํ์ฌ ๋จ๊ณ(์ธ๋ก์ค)์์ ๋์ ์ ์๋ row๋ 1, ๋์ ์ ์๋ row๋ 0
ll bit = row & ~((lx >> level) | (rx >> (N-level)));
// ์ตํ์ ๋นํธ๋ถํฐ ์์ ๋ฉด์ ๋ชจ๋ ๋นํธ๊ฐ ์์ด์ง๋๊น์ง ํ๋์ฉ ์ฌ๊ท
for(ll a=0; bit!=0; bit ^= a){
a = bit & (-bit); // bit์ ์ตํ์ ๋นํธ
// a์๋ฆฌ์ ๋์์ ๊ฒฝ์ฐ
row ^= a;
lx ^= a << level;
rx ^= a << (N-level);
// step์ ํ์ฉํด ๊ตฌํด์ผํ ๋ค์ ๋จ๊ณ๋ก ๋ฐ๋ก ์ ๊ทผ
if(backtracking(level + step[level])) {
ans[level] = a;
return true;
}
// ๋ฐฑํธ๋ํน
row ^= a;
lx ^= a << level;
rx ^= a << (N-level);
}
return false;
}
int main() {
ios_base::sync_with_stdio(0); cin.tie(0);
cin >> N;
row = (1 << N) - 1;
N--;
for(int i = 0; i <= N; i++) {
cin >> Q[i];
}
for(int i = 0; i <= N; i++){
// ์ด๋ฏธ ๋์ฌ์ง ๋ง ์ฒดํฌํด์ฃผ๊ธฐ
if(Q[i]){
// 1ull = 1์ ๊ทธ๋ฅ ์ฐ๋ฉด ๋ถํธ์๋ 32๋นํธ ์์์ด๋ฏ๋ก 64๋นํธ ์ฐ์ฐ์ ์ด์ํ ๊ฐ์ด ๋์ฌ ์ ์๋ค.
ans[i] = 1 << (Q[i]-1);
row ^= 1ull << (Q[i] - 1); // ๋์ ์ ์๋ ๊ณณ์ด 1
lx |= 1ull << (Q[i] - 1 + i); // ๋์ ์ ์๋ ๊ณณ์ด 1
rx |= 1ull << (Q[i] - 1 + N - i); // ๋์ ์ ์๋ ๊ณณ์ด 1
}
// 0์ด๋ผ๋ฉด ๋ค์์ ๊ตฌํด์ผ ํ ๊ณณ์ด ๋ช ์คํ
ํ์ธ์ง ๋ฏธ๋ฆฌ ๊ณ์ฐ
else {
int s = 1;
while(i + s <= N && Q[i+s]) ++s;
step[i] = s;
}
}
// backtracking ์์์ง์ ์ฐพ๊ธฐ
int start = 0;
while(start <= N && Q[start]) ++start;
// ํด๊ฐ ์์
if(!backtracking(start)){
cout << -1;
return 0;
}
// ๊ธฐ๋ก๋ i๋ฒ์งธ ๋นํธ๋ต์ ์ด์ฉํด ๋ต ์ถ๋ ฅ
for(int i = 0; i <= N; i++){
int j = 0;
while((1 << j) < ans[i]) j++;
cout << j+1 << ' ';
}
}
๐ก ๋ง๋ฌด๋ฆฌ
๋ง์ ์ฌ๋์ด 10๋ช ๋ ์๋๋ ๋ฌธ์ ๋ค. (๋ฌผ๋ก ํผ ์ฌ๋์ด ์ ์ด์๊ฒ ์ง๋งโฆ)
๋นํธ๋ง์คํน์ ์ ์ฉํ๊ธฐ๋ ์ด๋ ต์ง๋ง, ์ต์ ํ ์งํ์ ์ํ๋ฉด ์๊ฐ์ด๊ณผ๊ฐ ๋ฐ์ํ ์ ์๋ค.
ํผ์ ํ์๋ค๊ฐ ๋ค๋ฅธ ์ฌ๋์ ์ฝ๋๋ฅผ ์ฐธ๊ณ ํ๋ฉด์ ์ฃผ์์ ์จ๋ณด๋ฉด์ ๊น๋ํ๊ฒ ์ ๋ฆฌํ ์ฝ๋๋ค.
rust๋ก 236ms ๋ง์ ํผ ์ฌ๋์ด ์๋๋ฐ rust๋ ์ฝ์ ์๊ฐ ์์ด์ ํ์ฌ๋ ์ฝ๊ธฐ๋ฅผ ํฌ๊ธฐํ๋ค.