最近备考蓝桥,学习到递归模块,从最基本的八皇后及其变种开始刷起(如果可以穿越,我一定要抓到发明递归的那个人,然后把他干掉,造福后世的算法er,)。
题目大意
一个人,没孩子,要在死前分割财产,然后出了一个题,让人们做,也就是八皇后,8 * 8 的棋盘,棋盘有64个值,不同的放置方案有不同的和,求最大的和就可得出答案。
心路历程
读懂题意后很容易看出来这是一道八皇后的变种题,因此做此题前一定要理解且背写出八皇后代码。这里附上n皇后原理的视频讲解——>传送门
很快的敲出了八皇后的原码,与八皇后相比,本题第一个改变是如何求出每次递归结束后的Max值,下面两种方法都是可行的:要么列入参数递归, 要么在边界条件里+循环计算。
下一步是如何判断皇后之间是否产生冲突,不能用原八皇后的判定方法是因为这里需要计算Max值,因此定义数组vis,记录列、主对角线和副对角线的访问情况。
最后提交,AC,耗时3h左右。
代码展示
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
int C[50], tot = 0, n = 8, nc = 0;
int vis[3][50]; //记录 列,主对角(y-x), 副对角(y+x) 访问情况
int board[8][8];
int max_score;
void search(int cur) {
nc++;
if(cur==n) {
int score=0;
for(int i=0;i<8;i++) score+=board[i][C[i]];
max_score=max(max_score, score);
}
else for(int i=0;i<n;i++) {
//从第一列开始放皇后
if(vis[0][i] || vis[1][i-cur+n] || vis[2][i+cur]) //如果有冲突则结束
continue;
C[cur]=i;
vis[0][i]=vis[1][i-cur+n]=vis[2][i+cur]=1; //这个皇后填放成功,设置成有冲突
search(cur+1); //行数+1,填放下一个皇后
vis[0][i]=vis[1][i-cur+n]=vis[2][i+cur]=0; //填放完毕,冲突取消,(回溯)
}
}
int main() {
int k; scanf("%d", &k); while(k--) {
for(int i=0;i<8;i++) for(int j=0;j<8;j++) cin>>board[i][j];
memset(vis, 0, sizeof(vis));
max_score=0;
search(0);
printf("%5d\n", max_score);
}
return 0; }
如果这篇文章对你产生了帮助,就请给博主一个小小的赞吧!大家的点赞是我创作的最大动力!