N皇后问题

来源:互联网 发布:mac战网改地区 编辑:程序博客网 时间:2024/06/05 08:31

N皇后问题是一个非常非常经典的问题,是搜索中比较简单的问题,因此初次踏入这个坑,选择了它。。。

题目的大致意思是:在棋盘上放置n个皇后,使它们不能互相攻击。每个皇后的攻击范围是同行、同列以及同对角线(两条对角线),要求找出所有的解。

题目意思也可参照杭电oj上的,链接:hdu2553。

注:皇后的编号从0到n-1

解决方法:

按行放置皇后(因此不必考虑皇后是否会横向攻击),用一个一维数组C[]存储相关信息,其中C[x]表示第x行皇后所在列的编号。每放置一个皇后,都要判断它与前面的皇后是否会相互攻击(同列或者同对角线)

①同列:C[x]==C[y];

②同对角线:

i)主对角线

01234567-10123456-2-1012345-3-2-101234-4-3-2-10123-5-4-3-2-1012-6-5-4-3-2-101-7-6-5-4-3-2-10格子(x,y)的y-x标识了主对角线

因此可以用C[x]-x==C[y]-y判断两个皇后是否在同一条主对角线上。

ii).副对角线

0123456712345678234567893456789104567891011567891011126789101112137891011121314格子(x,y)的x+y标识了副对角线

因此可以用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;}
0 0