DFS-递归与回溯之The Sultan‘s Successors

题目:

The Sultan of Nubia has no children, so she has decided that the country will be split into up to k
separate parts on her death and each part will be inherited by whoever performs best at some test. It
is possible for any individual to inherit more than one or indeed all of the portions. To ensure that
only highly intelligent people eventually become her successors, the Sultan has devised an ingenious
test. In a large hall filled with the splash of fountains and the delicate scent of incense have been
placed k chessboards. Each chessboard has numbers in the range 1 to 99 written on each square and is
supplied with 8 jewelled chess queens. The task facing each potential successor is to place the 8 queens
on the chess board in such a way that no queen threatens another one, and so that the numbers on
the squares thus selected sum to a number at least as high as one already chosen by the Sultan. (For
those unfamiliar with the rules of chess, this implies that each row and column of the board contains
exactly one queen, and each diagonal contains no more than one.)
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.)

输入:

Input will consist of k (the number of boards), on a line by itself, followed by k sets of 64 numbers,
each set consisting of eight lines of eight numbers. Each number will be a positive integer less than
100. There will never be more than 20 boards.

输出:

Output will consist of k numbers consisting of your k scores, each score on a line by itself and right
justified in a field 5 characters wide.

输入样例:

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 64

输出样例:

260

题解题意及代码:

其实就是八皇后问题的升级,本题在八皇后要求每行有一个皇后,而且每行的皇后都不能在同行同列和斜对的基础上要求在8*8的图上都会有一个数,要求出皇后在满足八皇后的基础上,底数的和最大为多少。


这道题的思路就是dfs的深搜遍历出,所有摆好8行的皇后情况,以及他们的底数和。然后比较,选出最大的那个。

#include<bits/stdc++.h>
using namespace std;
const int maxn=10;
int tot,n;//tot是记录当前这个八皇后的底数和。
//n测试几组样例
int vis[maxn][maxn];//用于标记
int fmap[maxn][maxn];//存图
//判断皇后的位置是否合适的judge函数
int judge(int x,int y) {
	//上一行是否有其他皇后
	for(int i=x-1; i>=1; i--) {
		if(vis[i][y]) return 0;
	}
	//同一行是否有其他皇后
	for(int i=y-1; i>=1; i--) {
		if(vis[x][i]) return 0;
	}
	//对角线上是否有其他皇后
	for(int i=1; i<=8; i++) {
		for(int j=1; j<=8; j++) {
			if(abs(i-x)==abs(j-y)) {
				if(vis[i][j]) return 0;
			}
		}
	}
	return 1;
}
void dfs(int i,int fmax) {
	if(i>8) {//如果大于等于8那么已经放好了八个皇后 
		if(fmax>tot) tot=fmax;
		return;
	}
	for(int j=1;j<=8;j++){//第一行遍历过去找到所有能满足的点 
		if(vis[i][j]==0&&judge(i,j)){
			vis[i][j]=1;
			dfs(i+1,fmax+fmap[i][j]);//递归到下一行 
			vis[i][j]=0;//重新再找另一个位置另一种情况直到找到所有情况 
		}
	}
}
//主函数
int main(){
	scanf("%d",&n);
	while(n--){//存图 
		memset(vis,0,sizeof(vis));
		memset(fmap,0,sizeof(fmap));
		for(int i=1;i<=8;i++){
			for(int j=1;j<=8;j++){
				scanf("%d",&fmap[i][j]);
			}
		}
		tot=0;
		dfs(1,0);
		printf("%5d\n",tot);
	}
	return 0;
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以使用归与回溯函数来遍历数组中的所有数字,具体步骤如下: 1. 定义一个归函数,该函数将数组、当前遍历到的位置、已经遍历过的数字作为参数。 2. 在归函数中,先判断已经遍历的数字是否达到了数组的长度,如果是,则将当前的数字序列添加到结果中。 3. 如果没有遍历完整个数组,那么就从当前位置开始遍历数组中的每个数字,如果当前数字没有被遍历过,那么就将该数字添加到已经遍历过的数字序列中,并且归调用函数,将下一个位置和已经遍历的数字序列作为参数。 4. 回溯操作:在归函数返回时,将已经遍历的数字序列中最后一个数字删除,然后继续遍历下一个数字。 下面是一个示例代码: ```python def find_all_numbers(nums): res = [] def dfs(start, path): if len(path) == len(nums): res.append(path[:]) return for i in range(len(nums)): if nums[i] not in path: path.append(nums[i]) dfs(i+1, path) path.pop() dfs(0, []) return res ``` 这个函数的参数是一个整数数组 nums,返回值是一个二维数组,表示所有可能的数字序列。在函数中,定义了一个内部归函数 dfs,该函数的参数是起始位置 start 和已经遍历的数字序列 path。在归函数中,如果已经遍历的数字序列长度等于数组长度,就把当前的数字序列添加到结果中。否则,从起始位置开始遍历数组中的每一个数字,如果没有被遍历过,就将其添加到数字序列中,并且归调用函数。在归函数返回时,需要回溯操作,将已经遍历的数字序列中最后一个数字删除,然后继续遍历下一个数字。最后,调用 dfs 函数,并将其结果返回即可。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值