题意
给定n*n大小棋盘,皇后可以吃掉同行列斜线上的其他棋子。求棋子间不重复的摆法
源代码(数组栈
#include <iostream>
using namespace std;
long long stack[30],top,a[30],n,sum;
int check(long long k,long long p) //返回k行p列放置皇后是否冲突
{
for (int i=1;i<k;i++)
if (p-stack[i]==k-i || p-stack[i]==i-k)
return 1;
return 0;
}
int main()
{
cin>>n;
top=1;
sum=0;
while (!stack[0]) //第一行尝试结束,stack0 会递增,于是不达成条件退出循环
{
if (top>n) { //top代表将要摆放第几行的棋子,大于n即是有解
cout<<"find out:-------------"<<endl;
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
cout<<(stack[i]==j?1:0)<<(j==n?'\n':' ');
top--;
sum++;
continue;
}
if (a[stack[top]]) {
//对于该处,只有两种情况,1、从第一行的摆放到top行stack【top】摆放棋子的情况已经尝试完毕
//2、在运行到此处前发生了top递增,也就是试探该行能放置的位置,即stack【top】=0的情况,不影响程序
a[stack[top]]=0;
}
stack[top]++; //这里是往后找能放置的位置,如果找不到,就会大于n
while ( (a[stack[top]] || check(top,stack[top])) && stack[top]<=n)
stack[top]++;
if (stack[top]>n) { //大于n的话这行尝试结束,返回上行。
stack[top]=0;
top--;
continue;
} else { //往下一层尝试
a[stack[top]]=1;
top++;
stack[top]=0;
}
}
cout<<endl<<"total "<<sum<<" kinds of result."<<endl;
return 0;
}
源代码(回溯)
#include <iostream>
using namespace std;
int a[15],b[15],n,sum;
void find(int k) //K为试探的第几行
{
if (k>n) //k>n就是找到一个结果
{
sum++;
return ;
}
int used; //用来判断是哦夫和斜线重合的变量
for (int i=1;i<=n;i++)
if (!b[i]) { //列不冲突
used=1;
for (int j=1;j<k;j++) //盘斜线是否冲突
if ( k-j == a[j]-i || a[j]-i==j-k) {
used=0;
break;
}
if (!used) continue;
b[i]=1; //标记i列被使用
a[k]=i; //标记k行I列
find(k+1); //进入下一行判断
b[i]=0;
}
}
int main()
{
cin>>n;
find(1);
cout<<sum<<endl;
return 0;
}