b510. M 皇后 N 城堡 5/16/2025

解法一、窮舉

col, diag1, diag2
分別儲存 直列 斜線 的棋子占用狀態

當一直線有 皇后城堡 占用,則 不能放置城堡 不能放皇后
當一斜線有 皇后 占用,則 不能放置城堡 不能放皇后
當一斜線有 城堡 占用,則 只能放置城堡 不能放皇后 (皇后會攻擊到之前放的城堡)

遞迴結束記得恢復原本占用狀態 (注意 城堡 放置後的復原)

✅ 完整代碼

評分結果(參考) : AC (3ms, 336KB)

#include <bits/stdc++.h>
using namespace std;

int m, n, size, cnt=0;
vector<int> col, diag1, diag2;


void setFlag(int r, int c, int col_, int diag1_, int diag2_){
    col[c] = col_;
    diag1[r+c] = diag1_;
    diag2[r-c+size-1] = diag2_;
}

void dfs(int qLeft, int cLeft, int r){
    if(r >= size){
        if(qLeft==0 && cLeft==0) cnt++;    
        return;
    }
    
    // 0 : Nothing
    // 1 : Queen
    // 2 : Castle
    for(int i=0; i<size; i++){
        // place Queen
        if(qLeft>0 && col[i]==0 && diag1[r+i]==0 && diag2[r-i+size-1]==0){
            setFlag(r, i, 1, 1, 1);
            dfs(qLeft-1, cLeft, r+1);
            setFlag(r, i, 0, 0, 0);
        }

        // place Castle
        if(cLeft>0 && col[i]==0 && diag1[r+i]!=1 && diag2[r-i+size-1]!=1){
            int diag1_temp = diag1[r+i];
            int diag2_temp = diag2[r-i+size-1];

            setFlag(r, i, 2, 2, 2);
            dfs(qLeft, cLeft-1, r+1);
            setFlag(r, i, 0, diag1_temp, diag2_temp);
        }
    }
}

int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    cin >> m >> n;
    size = m + n;

    col.assign(size, 0);
    diag1.assign(2*size, 0);
    diag2.assign(2*size, 0);
    
    dfs(m, n, 0);
    cout << cnt;

    return 0;
}