n * nのチェス盤にn個のクイーンを配置し、同じ行と同じ列を必要とします。2つのスラッシュは配置できません。
これは単純なバックトラック問題です。
しかし、それが解放できるかどうかを判断する方法は難しいです。
そのとき、この座標を置けるかどうかを判断するために、2次元配列を開くことを考えました。
しかし、ここに問題があります。2つのクイーン(1と2)のスラッシュにフォーカスがある場合があります。次に、バックトラック(クイーン2からのバックトラック)時にこの座標をリセットします。しかし、この場合、クイーン1のスラッシュは効果がありません。
女王は0行目から配置され、行には女王が1つしか存在できないため、i番目の女王はi番目の行でもあります。
表現するために配列フラグを使用します。flag[i]=j
これは、行iのクイーンが列jに配置されていることを示しています。
このように、対角線を考える場合、2点直線の傾き(Y1-Y2 / X1-X2)を使用できます。
#include<iostream>
#include<set>
#include<vector>
using namespace std;
int ans=0;
int flag[100];//flag[i]=j, 第i个皇后的列数j
bool place(int col,int row){
for(int i=0;i<row;i++){ //找出已经放置的queen的行,判断他们与将要放的queen是否冲突
if(flag[i]==col||abs(i-row)==abs(col-flag[i])) return false;
}
return true;
}
void dfs(int n,int row){
if(row==n){
ans++;
return;
}
for(int i=0;i<n;i++){//列数
if(place(i,row)){//判断第row行,第i列可不可以放queen
flag[row]=i;
dfs(n,row+1);
//flag[row]=0;
//发现去掉这里也没事,原因:我们先判断再放,所以回溯也没事。
}
}
}
int main(void){
int n=4;
dfs(n,0);
cout<<ans;
}