N皇后问题是一个非常非常经典的问题,是搜索中比较简单的问题,因此初次踏入这个坑,选择了它。。。
题目的大致意思是:在棋盘上放置n个皇后,使它们不能互相攻击。每个皇后的攻击范围是同行、同列以及同对角线(两条对角线),要求找出所有的解。
题目意思也可参照杭电oj上的,链接:hdu2553。
注:皇后的编号从0到n-1
解决方法:
按行放置皇后(因此不必考虑皇后是否会横向攻击),用一个一维数组C[]存储相关信息,其中C[x]表示第x行皇后所在列的编号。每放置一个皇后,都要判断它与前面的皇后是否会相互攻击(同列或者同对角线)
①同列:C[x]==C[y];
②同对角线:
i)主对角线
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
| -1 | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
| -2 | -1 | 0 | 1 | 2 | 3 | 4 | 5 |
| -3 | -2 | -1 | 0 | 1 | 2 | 3 | 4 |
| -4 | -3 | -2 | -1 | 0 | 1 | 2 | 3 |
| -5 | -4 | -3 | -2 | -1 | 0 | 1 | 2 |
| -6 | -5 | -4 | -3 | -2 | -1 | 0 | 1 |
| -7 | -6 | -5 | -4 | -3 | -2 | -1 | 0 |
因此可以用C[x]-x==C[y]-y判断两个皇后是否在同一条主对角线上。
ii).副对角线
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
| 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
| 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
| 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
| 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
| 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
| 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
因此可以用C[x]+x==C[y]+y判断两个皇后是否在同一条副对角线上。
解决此问题的重要思路是回溯:若当前放置的皇后与前面的有冲突,就要返回上一级重新,放置新的皇后。
注意要有预处理,否则就TLE(Time Limit Exceeded)(超时),第一次就因为没有预处理超时了。。。
预处理如下:
for(n=1;n<=10;n++){ tot=0; search(0); a[n]=tot; }
代码如下:
</pre><pre name="code" class="cpp">#include<iostream>
using namespace std;
int C[11];
int tot;
int n;
void search(int cur)
{
if(cur==n) tot++;
else for(int i=0;i<n;i++){
int ok=1;
C[cur]=i;
for(int j=0;j<cur;j++){
if(C[cur]==C[j]||cur+C[cur]==j+C[j]||cur-C[cur]==j-C[j]){
ok=0;
break;
}
}
if(ok) search(cur+1);
}
}
int main()
{
int a[11];
for(n=1;n<=10;n++){
tot=0;
search(0);
a[n]=tot;
}
while(cin>>n&&n){
cout<<a[n]<<endl;
}
return 0;
}

548

被折叠的 条评论
为什么被折叠?



