#include<bits/stdc++.h>
const ll mod = 1e9+7;
const int N = 1e5+20;
#define dep(i,a,b) for(int i=(a);i>=(b);i--)
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define mes(p) memset(p,0,sizeof(p))
using namespace std;
int ans=0,a[15][15],n,check[3][50],h[15];
void dfs(int r,int l){
if(r==n+1){
if(++ans<=3){
rep(i,1,n)
cout<<h[i]<<' ';
cout<<endl;
}
return;
}
rep(l,1,n)
if(!check[2][l]&&!check[1][l+r]&&!check[0][l-r+n]) {
check[2][l]=check[1][l+r]=check[0][l-r+n]=1;
h[r]=l;
dfs(r+1,1);
check[2][l]=check[1][l+r]=check[0][l-r+n]=0;
}
}
int main()
{
cin>>n;
mes(a);mes(check);mes(h);
dfs(1,1);
cout<<ans;
return 0;
}
check保证了每列和每条对角线上只有一个棋子,具体机制如下,没有一些奇奇怪怪难以理解的公式:
check[2]储存了棋子的列数
check[0]和check[1]储存对角线上的棋子分布情况:
对于一条从右上到左下的对角线,其上的棋子坐标应满足x+y为一定值;
对于一条从左上到右下的对角线,其上的棋子坐标应满足x-y为一定值,为了避免负数的产生,代码中用y-x+n来储存数字,具体效果读者可以自行研究。