(超详解)八皇后*改--求八个位置和的最大值

题目

在这里插入图片描述

八皇后三步走

  • 第一步:挑选能放皇后的位置。
  • 第二步:在放了皇后的位置处更新,一直在第一步和第二部步反复横跳,直到放好了八皇后。
  • 第三步:放好八皇后之后,更新答案,并回溯到之前的过程,回到第一步。

这样文字描述应该很难想到代码怎么实现。
首先我们要能够回到上一个过程,我们可以使用回溯算法,其次每次挑选皇后的位置时需要判断,我们可以单独写一个函数判断是否可以放置皇后。

总纲介绍:

  1. 根据放置位置的行列写出函数isValid()用于判断该位置的上、左上、右上是否已经放置过皇后来实现对是否可放置的判断。
  2. dfs()回溯函数,回溯函数的过程实际上时一个选择与撤销的过程,具体可以看后面的代码。
  3. 基本用到的数据存储结构–我用bool数组存储该位置是否放置皇后,而原先的八皇后所在的位置不作更改,用于累加数据。每次回溯得到每八个皇后的数据和后,我将他存入ans数组,最后再判断ans数组中的最大值即可。

isValid()函数实现

//根据行和列判断是否可放置
bool isValid(int row,int col){
    //检查上面的行
    for (int i = 0; i < row; i++){
        if(place[i][col])
            return false;
    }//检查左上角
    for(int i=row-1,j = col-1;i>=0&&j>=0;i--,j--){
        if(place[i][j])
            return false;
    }//检查右上角
    for (int i = row-1,j = col+1; i >=0&&j<8; i--,j++){
        if(place[i][j])
            return false;
    }
    return true;
    
}

dfs()函数实现

void dfs(vector<vector<int> >&chess,int row){
    if(row==8){
        ans.push_back(res);
        return;
    }
    for(int col=0;col<8;col++){
        //排除不能放的位置
        if(!isValid(row,col))
            continue;
        //进行回溯
        place[row][col] = true;
        res += chess[row][col];
        dfs(chess,row+1);
        res -= chess[row][col];
        place[row][col] = false;
    }
}

主函数输入输出接口:

int main(){
vector<vector<int> >chess(8,vector<int>(8));
for(int i=0;i<8;i++){
    for(int j=0;j<8;j++){
        cin>>chess[i][j];
    }
}
dfs(chess,0);
int t = *max_element(ans.begin(),ans.end());
cout<<t;
return 0;        
}

完整代码:


#include<bits/stdc++.h>
using namespace std;
int res = 0;
vector<int>ans;
vector<vector<bool> >place(8,vector<bool>(8));
//根据行和列判断是否可放置
bool isValid(int row,int col){
    //检查上面的行
    for (int i = 0; i < row; i++){
        if(place[i][col])
            return false;
    }//检查左上角
    for(int i=row-1,j = col-1;i>=0&&j>=0;i--,j--){
        if(place[i][j])
            return false;
    }//检查右上角
    for (int i = row-1,j = col+1; i >=0&&j<8; i--,j++){
        if(place[i][j])
            return false;
    }
    return true;
    
}
void dfs(vector<vector<int> >&chess,int row){
    if(row==8){
        ans.push_back(res);
        return;
    }
    for(int col=0;col<8;col++){
        //排除不能放的位置
        if(!isValid(row,col))
            continue;
        //进行回溯
        place[row][col] = true;
        res += chess[row][col];
        dfs(chess,row+1);
        res -= chess[row][col];
        place[row][col] = false;
    }
}

int main(){
vector<vector<int> >chess(8,vector<int>(8));
for(int i=0;i<8;i++){
    for(int j=0;j<8;j++){
        cin>>chess[i][j];
    }
}
dfs(chess,0);
int t = *max_element(ans.begin(),ans.end());
cout<<t;
return 0;        
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值