38 lines of code AC-UVA-167 The Sultan's Successors (Eight Queens problem, with video explanation)

I recently prepared for the Lanqiao exam and learned the recursive module, starting with the most basic eight queens and their variants (if it can be traversed, I must catch the person who invented recursion, and then kill him, which will benefit future generations.) .


Topic

A person, without a child, wants to divide his property before death, and then asks people to do a question, that is, eight queens, 8 * 8 chessboard, the chessboard has 64 values, and different placement schemes have different sums. The largest sum can be the answer.


Mental journey

After reading the meaning of the question, it is easy to see that this is a variant of the eight queens, so you must understand and memorize the eight queens code before doing this. Attached here is a video explanation of the principle of n queens -> portal

I quickly knocked out the original code of the eight queens. Compared with the eight queens, the first change in this question is how to find the Max value after each recursion. The following two methods are feasible: either include the parameter recursion , Or in the boundary conditions + loop calculation.

The next step is how to judge whether there is a conflict between the queens. The original eight-queen judgment method cannot be used because the Max value needs to be calculated here, so the array vis is defined to record the access status of the column, the main diagonal and the sub-diagonal.

The final submission, AC, took about 3h.


Code display

#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; }

If this article has helped you, please give the blogger a small like! Everyone's likes are the biggest motivation for my creation!

Guess you like

Origin blog.csdn.net/weixin_43899069/article/details/108083032