N queen problem (simple retrospective)

Problem Description:

N queens are placed on the N*N checkerboard, so that they do not attack each other (that is, any two queens are not allowed to be in the same row, the same column, and are not allowed to be on the diagonal line that is 45 angles to the border of the chessboard. .Your task is to find out how many legal placement methods there are for a given N.

enter:

There are several rows, each with a positive integer N≤10, indicating the number of chessboards and queens; if N=0, it means the end.

Output:

There are several rows, each with a positive integer, which represents the different placement quantity of the queen corresponding to the input row.

Sample Input

1
8
5
0

Sample Output

1
92
10

[Thinking]: If the amount of data is small, you can go back directly with violence. If you optimize, you can open a vis array to mark the queen that was previously placed. Just start from the first line of the n*n chessboard and go down. The following code starts from 0, so I wrote it to search from the 0th line. Let me talk about the condition of backtracking, that is, the condition of ending the "leaf node" (I call the deepest row a leaf node) recursion, that is, when k (your current number of rows) can find the nth row That is, when one goes beyond the next line of the board, it can be backtracked.

Then if the end condition is not met, then assume that you put the queen on each column of the change line to see which columns are feasible. Pay attention to the unsatisfied conditions here, because only one queen can be placed in each row, so you only need to judge whether it is in a column, left slash, right slash. Remember, the absolute value of the left slash cannot be calculated, and the two coordinates can be subtracted and judged to be equal. If the absolute value is added, the conditions at the upper right and lower left of the diagonal will be mixed. So you can just use the coordinate characteristics to judge. If you don't understand, you can draw a blank coordinate system by yourself, and look at the relationship between the ordinate and abscissa of points on the same oblique line. It is not difficult to see.

The code is given below.

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <queue>
#include <stack>

using namespace std;
#define LL long long

const int N = 1e5 + 7;
const int inf = 0x3f3f3f3f;
const int M = 1e9 + 7;
int a[20];
int cnt,n;//n为n个皇后 棋盘大小为n*n cnt代表多少种放置方法

void f(int k)//一行一行的递归 然后进行回溯
{
    if(k>=n){
//只要把棋盘都放完即可 即结束递归的条件就是传入的值比棋盘行数大一 我这从0开始所以等于n就可
        cnt++;
        return ;
    }
    else
    {
        for(int i=0;i<n;i++){
            bool flag = false;
            a[k] = i;//在第k行i列上
            for(int j=0;j < k;j++){//看是否出现皇后的冲突 和已经放上的判断 就判断那三个条件
                    //不可求绝对值 不然在对角线右上方和左下方的情况会判断错误 刚刚脑子一懵添了个绝对值 
                if(a[j]==a[k]||(j-a[j])==(k-a[k])||(a[k]+k)==(a[j]+j))//判断是否在一列 左斜 右斜
                {
                    flag = true;
                    break;
                }
                   /*if((a[j]==a[k])||(abs(k-j)==abs(a[j]-a[k]))){//如果这样的话是可以加绝对值来表示两点共线的 y2-y1/(x2-x1)=+1/-1;
                    flag = true;
                    break;
                }*/
            }
            if(flag==false)
            {
                f(k+1);
            }
        }
    }
}


int main(){

    while(cin>>n){
        if(n==0)
            break;
        cnt = 0;
        f(0);//从第0行开始递归 先在棋盘第一行放入一个皇后
        cout<<cnt<<endl;
    }
    return 0;
}

 

Guess you like

Origin blog.csdn.net/Puppet__/article/details/83104411