HDOJ 1642
Write a program that will read in the number and details of the chessboards and determine the highest scores possible for each board under these conditions. (You know that the Sultan is both a good chess player and a good mathematician and you suspect that her score is the best attainable.)
八皇后问题 一直在hdoj上无法通过 都是 超时 ,首先是自己尝试写了一遍,用flag数组标记是否可以占据位置,但就是超时了。
然后就看着视频做,用row[8],ld[15],rd[15]三个数组来标记列,左对角线,右对角线,但还是超时;
然后百度搜索,用经典的递归算法,超时;
最后用位运算,才算通过。
#include <stdio.h>
//值的初始化问题
int num[8][8];
int x[8];
int count;
int upperlim;
void findEight(int row, int ld, int rd, int i);
int main() {
int k;
scanf("%d", &k);
while (k-->0) {
upperlim = 1;
int i, j;
for (i = 0; i<8; i++) {
for (j = 0; j<8; j++) {
scanf("%d", &num[i][j]);
}
}
count=0;//一定要初始化
upperlim = (upperlim << 8) - 1;//8皇后得到8列1
findEight(0, 0, 0, 0);
printf("%5d\n", count);
}
}
void findEight(int row, int ld, int rd, int q) {
if (row == upperlim) {
int sum = 0;
int i = 0;
for (i = 0; i<8; i++)
sum += num[i][x[i]];
if (sum>count)
count = sum;
return ;
}
int d = upperlim&(~(row | ld | rd));//为1的为可用的位置
while (d) {
int pos = d&-d;//得出d中最右边为1的位置
int flag = pos;
int k = 0;
while (flag != 0) {
k++;
flag=flag >> 1;
}
x[q] = (8 - k);
d -= pos;//最右边的位置1被使用变为0
findEight(row | pos, (ld|pos) << 1, (rd | pos) >> 1, q + 1);//列 、左对角线、右对角线
}
}