八皇后问题(递归回溯+迭代回溯)

        八皇后问题是一个以国际象棋为背景的问题:如何能够在 8×8 的国际象棋棋盘上放置八个皇后,使得任何一个皇后都无法直接吃掉其他的皇后?为了达到此目的,任两个皇后都不能处于同一条横行、纵行或斜线上。八皇后问题可以推广为更一般的n皇后摆放问题:这时棋盘的大小变为n×n,而皇后个数也变成n。当且仅当 n = 1 或 n ≥ 4 时问题有解。


#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<map>
#include<queue>
#include<stack>
#include<vector>
#include<algorithm>
#include<cstring>
#include<string>
#include<iostream>
#include<windows.h>
#define ms(x,y) memset(x,y,sizeof(x))
const int MAXN=1000+10;
const int INF=1<<30;
using namespace std;
int vis[MAXN][MAXN];
int c[60]; //c[i] 表示第i行的皇后所在的列号
int cnt;

/* -------------------------------------------------------------- */

void eight_queen(int cur, int n) //递归1
{
    int i, j, ok;
    if(cur == n) {
        cnt++;
        /*
        for(i=0; i<n; i++){
            for(j=0; j<n; j++){
                if(j == c[i]) printf("# ");
                else printf(". ");
            }
            printf("\n");
        }
        printf("\n%d\n\n", cnt);
        */
        return;
    }
    for(i=0; i<n; i++){
        c[cur] = i;
        ok=1;
        for(j=0; j<cur; j++){
            if(i == c[j] || cur - i == j - c[j] || cur + i == j + c[j]){
                ok=0; 
                break;
            }
        }
        if(ok) eight_queen(cur+1, n);
    }
}

/* -------------------------------------------------------------- */

void eight_queen1(int cur, int n) //递归2
{
    int i, j;
    if(cur == n){
        cnt++;
        /*
        for(i=0; i<n; i++){
            for(j=0; j<n; j++){
                if(j == c[i]) printf("# ");
                else printf(". ");
            }
            printf("\n");
        }
        printf("\n%d\n\n", cnt);
        */
        return;
    }
    for(i=0; i<n; i++){
        c[cur] = i;
        if(!vis[0][i] && !vis[1][cur+i] && !vis[2][cur-i+n]){
            vis[0][i]=vis[1][cur+i]=vis[2][cur-i+n]=1;
            eight_queen1(cur+1, n);
            vis[0][i]=vis[1][cur+i]=vis[2][cur-i+n]=0;
        }
    }
}

/* -------------------------------------------------------------- */

bool Judge(int r, int c, int n) //迭代
{
    if(!vis[0][c] && !vis[1][r + c] && !vis[2][r - c + n]){
        vis[0][c] = vis[1][r + c] = vis[2][r - c + n] = 1;
        return 1;
    }
    return 0;
}

void SetZero(int r, int c, int n)
{
    vis[0][c] = vis[1][r + c] = vis[2][r - c + n] = 0;
}

void eight_queen2(int cur, int n)
{
    int i, j, C, R;
    c[cur] = -1;
    while(cur >= 0)
    {
        c[cur]++;
        while(c[cur] < n && !Judge(cur, c[cur], n)) //在该行寻找适合的列
            c[cur]++;
        if(c[cur] < n){
            if(cur == n - 1){
                cnt++;
                /*
                for(i=0; i<n; i++){
                    for(j=0; j<n; j++){
                        if(j == c[i]) printf("# ");
                        else printf(". ");
                    }
                    printf("\n");
                }
                printf("\n%d\n\n", cnt);
                */
                SetZero(cur, c[cur], n);
            }
            else{ //处理下一行皇后
                cur++;
                c[cur] = -1;
            }
        }
        else{ //回溯
            cur--;
            SetZero(cur, c[cur], n);
        }
    }
}

/* -------------------------------------------------------------- */

int main()
{
    int n = 13;
    FILETIME beg,end;
    GetSystemTimeAsFileTime(&beg);
    eight_queen2(0, n);
    GetSystemTimeAsFileTime(&end);
    int dur = 100*(end.dwLowDateTime-beg.dwLowDateTime);
    printf("%d\n", dur);
    printf("%d\n", cnt);
    return 0;
}
    原文作者:八皇后问题
    原文地址: https://blog.csdn.net/u013351484/article/details/44873077
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞