题目
八皇后三步走
- 第一步:挑选能放皇后的位置。
- 第二步:在放了皇后的位置处更新,一直在第一步和第二部步反复横跳,直到放好了八皇后。
- 第三步:放好八皇后之后,更新答案,并回溯到之前的过程,回到第一步。
这样文字描述应该很难想到代码怎么实现。
首先我们要能够回到上一个过程,我们可以使用回溯算法,其次每次挑选皇后的位置时需要判断,我们可以单独写一个函数判断是否可以放置皇后。
总纲介绍:
- 根据放置位置的行列写出函数isValid()用于判断该位置的上、左上、右上是否已经放置过皇后来实现对是否可放置的判断。
- dfs()回溯函数,回溯函数的过程实际上时一个选择与撤销的过程,具体可以看后面的代码。
- 基本用到的数据存储结构–我用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;
}