[๋ฐฑ์ค€] [C++] ๐Ÿงฉ N-Queen (Hard) 30243๋ฒˆ

๐Ÿ’ก ๋ฌธ์ œ ์„ค๋ช…

๐Ÿงฉ N-Queen (Hard)

๊ธฐ์กด์˜ 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๋Š” ์ฝ์„ ์ˆ˜๊ฐ€ ์—†์–ด์„œ ํ˜„์žฌ๋Š” ์ฝ๊ธฐ๋ฅผ ํฌ๊ธฐํ–ˆ๋‹ค.