努比亚和苏丹没有子女,所以他要从一些有集成资格的继承者中挑选一个出来继承王位。他希望这个继承者足够聪明,所以他准备了一个西洋棋盘,上面的每个格子中均有一个 1-991−99 的数字。他又准备了 88 个皇后棋子。
88 皇后的规则就是不能有任何棋子同行或者同列或者同斜线,在满足这个规则的同时,王位继承者还需要让 88 个皇后所在的位置的数字的和是最大的。
输入格式
输入一个数字 k(k\leq 20)k(k≤20),代表棋盘的数量。
接下来有 kk 个棋盘,每个棋盘有 6464 个数字,分成 88 行 88 列出入,具体可见样例,每一个数字均小于 100100。
输出格式
每一个棋盘对应输出最大的数值, 一共输出 kk 行。
Sample Input
1 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 64Sample Output
260
题目类型:dfs
吐槽:本来以为8*8的二维不会爆,但是第一遍写很麻烦,还死循环。
解题思路及注意点:
1)把二维数组抽成一维数组 ,反正一直都是64个格子,temp数组记录已经选中的皇后。
3)出口是x(已找到的皇后数)达到8;
4)写一个check()函数来判断皇后是否符合条件;
是否在同一行:遍历行数组
是否在同一列:遍历列数组
是否在同一斜线上:横坐标之差的绝对值 == 纵坐标的绝对值
5)有多组棋盘,数据记得清零。
#include <bits/stdc++.h>
#define rep(x ,a, b) for(int x =a; x<=b; x++)
#define inf 0x3f3f3f3f
using namespace std;
const int N= 15;
int n;
int cot;
int temp1[8], temp2[8];
int board[9][9];
int ans;
void init()
{
memset(temp1, 0, sizeof(temp1));
memset(temp2, 0, sizeof(temp2));
rep(i, 1, 8)
{
rep(j, 1, 8)
{
scanf("%d", &board[i][j]);
}
}
cot = 0;
ans = 0;
}
bool check(int i, int j, int x)
{
if(x != 0)
{
for(int k=0; k<x; k++)
{
if(temp1[k] == i) return false;
if(temp2[k] == j) return false;
if(abs(temp1[k] - i) == abs(temp2[k] - j)) return false;
}
}
return true;
}
void dfs(int x, int value, int pre)
{
if( x== 8)
{
ans = max(ans, value);
//cout<<ans<<endl;
return ;
}
else
{
rep(i, pre+1, 64)
{
int a = i/8+1;
int b = i%8;
if(i%8 == 0)
{
a--;
b = 8;
}
if(check(a, b, x))
{
temp1[x] = a;
temp2[x] = b;
dfs(x+1, value+board[a][b], i);
}
}
}
}
int main()
{
scanf("%d", &n);
rep(i, 1, n)
{
init();
dfs(0, 0, 0);
printf("%d\n", ans);
}
return 0;
}