16 8皇后·改
8皇后问题:
在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上问有多少种摆法。8皇后是典实际上一个类似枚举的搜索尝试过程,它的的基本思想是在所有的解空间中,先深度搜索求出一种解法不满足约束条件的解时,回退到之前的解,继续对问题求解8皇后也可以推广为一般情形,将棋盘扩展为n*n,此时皇后个数n(n=1或>=4时有解)。
思路:逐行放置,逐列搜索。从当前行的第一列开始搜索,判断该位置是否合法。合法则递归判断下一行,不合法则搜索下一列,直到最后一列也不符合,或者在最后一行放下棋子就返回上一次递归,一直到第一行遍历完毕。
问题描述 :
规则同8皇后问题,但是棋盘上每格都有一个数字,要求八皇后所在格子数字之和最大。
输入说明 :
一个8*8的棋盘。
数据规模和约定棋盘上的数字范围0~99
输出说明 :
所能得到的最大数字和
输入范例 :
1 2 3 4 5 6 7 8
9 10 11 12 13 14 15 16
17 18 19 20 21 22 23 24
25 26 27 28 29 30 31 32
33 34 35 36 37 38 39 40
41 42 43 44 45 46 47 48
48 50 51 52 53 54 55 56
57 58 59 60 61 62 63 64
输出范例 :
260
#include<stdio.h>
#include<math.h>
int sum,max;
int a[8][8],pos[8];
int isLegal(int row,int col){
//用于是按行逐级筛选,故不用考虑同行情况,只需考虑是否同列,或者在同一对角线上
for(int i=0;i<row;i++){
//同列
if(pos[i]==col){
return 0;
}
//同一对角线上 pos[]数组里面存放的是对应的行里选取的列的值
//处于同一对角线上的坐标(x1,y1),(x2,y2) |y1-y2|==|x1-x2|
if(abs(pos[i]-col)==abs(i-row)){
return 0;
}
}
return 1;
}
//深度优先遍历
void DFS(int row){
//递归返回条件
if(row==8){
if(sum>max){
max=sum;
}
return;
}
for(int col=0;col<8;col++){
if(isLegal(row,col)){
pos[row]=col;
sum+=a[row][col];
//进入下一行
DFS(row+1);
//sum清零,方便下一次统计
sum-=a[row][col];
}
}
}
int main(){
for(int i=0;i<8;i++){
for(int j=0;j<8;j++){
scanf("%d",&a[i][j]);
}
}
max=-0x3F3F3F3F;// -0x3f3f3f3f=-1061109567,表示无穷小
sum=0;
DFS(0);
printf("%d\n",max);
return 0;
}