八皇后问题(递归)

来源:互联网 发布:网络用语蛤蟆啥意思 编辑:程序博客网 时间:2024/06/04 20:17

八皇后问题

Feynman和朋友们下国际象棋,(棋盘为8x8)。下到兴致之处,Feynman突发奇想:如果将64个格子分别赋值,并拿出八个皇后棋子(国际象棋中的皇后可以将同一行、同一列和同一对角线上的对方棋子吃掉。)

Feynman想怎么摆放这八个皇后的位置才能让她们不互相攻击的同时八个皇后所在格子的和最大。

输入格式

每个棋盘有64个数字,分成88列输入,就如样例所示,分别表示格子的值。棋盘上每一个数字均小于100

输出格式

输出一个最大的总和

样例输入

1  2  3  4  5  6  7  89 10 11 12 13 14 15 1617 18 19 20 21 22 23 2425 26 27 28 29 30 31 3233 34 35 36 37 38 39 4041 42 43 44 45 46 47 4848 50 51 52 53 54 55 5657 58 59 60 61 62 63 64

样例输出

260


思路

利用递归的思想(DFS),搜索每行(因为满足皇后不冲突,一行只能摆放一个皇后)

设置标记数组,分别标记列,主对角线,次对角线。每次递归时(扫描行),枚举每列的情况,如果列没有标记,利用行列坐标计算出所在的主对角线和次对角线,判断两条对角线上有无标记,若行列对角线都无标记就将一个皇后放置在该坐标上,如果后续递归完不成任务(八皇后冲突了),递归退到前步,sum减坐标对应值,去除标记(dfs常用做法)。如果满足情况,在sum中遴选max即可。



如图红色对角线序号可由坐标表达式:7-l+i求得    黑色对角线序号可由坐标表达式l+i求得


代码示例

#include<iostream>using namespace std;int map[10][10];int lie[8];//标记列 //直接标记共30条对角线,就不用一个个点进行x,y关系的比较了 int dui1[15];//标记从对角线 int dui2[15];//标记主对角线 int n=8;int sum=0;int max_x=-0xfffff;void dfs(int l)//对行进行dfs {if(l==8){//cout<<sum<<"..."<<endl;if(max_x<sum) max_x=sum;return ;}for(int i=0;i<8;++i){if(lie[i]==0&&dui1[7-l+i]==0&&dui2[l+i]==0){sum+=map[l][i];lie[i]=1;dui1[7-l+i]=1;dui2[l+i]=1;dfs(l+1);sum-=map[l][i];lie[i]=0;dui1[7-l+i]=0;dui2[l+i]=0;}}}int main(){for(int i=0;i<n;++i){for(int j=0;j<n;++j){cin>>map[i][j];}}dfs(0);cout<<max_x<<endl;return 0;} 



1 0
原创粉丝点击