38行代码AC——UVA-167The Sultan‘s Successors(八皇后问题,附视频讲解)

最近备考蓝桥,学习到递归模块,从最基本的八皇后及其变种开始刷起(如果可以穿越,我一定要抓到发明递归的那个人,然后把他干掉,造福后世的算法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; }

如果这篇文章对你产生了帮助,就请给博主一个小小的赞吧!大家的点赞是我创作的最大动力!

猜你喜欢

转载自blog.csdn.net/weixin_43899069/article/details/108083032