码迷,mamicode.com
首页 > 其他好文 > 详细

八皇后

时间:2015-06-23 23:12:50      阅读:142      评论:0      收藏:0      [点我收藏+]

标签:回溯   递归   

八皇后(可以扩展为N皇后问题)

每行每列每个对角线都不允许有两个或两个以上的皇后


回溯,递归求解

#include<iostream>/// 八皇后
#include<cstdio>
using namespace std;
int c[10]; /// 第i行 列为a[i]
int total;
int n;
/// 在一条主对角线上 则它们的 x-y相同   y=x+b
/// 在一条负对角线上 则它们的 x+y相同   y=-x+b
int v[3][100]; /// v[0]列   v[1]主对角线  v[2]负对角线

int dfs_1(int cur) // 填充第cur行
{
    if(cur==n){
            total++;
            //for(int i=0;i<n;i++)
            //    printf("%d %d\n",i,c[i]);
            //puts("\\\\");
    }
    else{
        for(int i=0;i<n;i++){// 列
            int ok=1;
            for(int j=0;j<cur;j++)//行
                if(c[j]==i||cur-j==i-c[j]||cur-j==c[j]-i) // 存在两元素在 同一列 或对角线
                      ok=0;          // or if(c[j]==i||abs(cur-j)==abs(i-c[j]))
            if(ok){//puts("[]");
                c[cur]=i;
                dfs_1(cur+1);
            }
        }
    }
}

/// 优化 
int dfs_2(int cur) // 填充第cur行
{
    if(cur==n){
            total++;
            //for(int i=0;i<n;i++)
            //    printf("%d %d\n",i,c[i]);
            //puts("\\\\");
    }
    else{
        for(int i=0;i<n;i++){// 列,即第cur个皇后放在第i列上
            if(!v[0][i]&&!v[1][cur-i+n]&&!v[2][cur+i]){  // 第cur行第i个列的同列,主对角线,副对角线上均没有元素
                v[0][i]=v[1][cur-i+n]=v[2][cur+i]=1;
                c[cur]=i;
                dfs_2(cur+1);
                v[0][i]=v[1][cur-i+n]=v[2][cur+i]=0;
            }
        }
    }
}


int main()
{
    total=0;
    n=8;
    dfs_1(0);
    cout<<total<<endl;

    total=0;
    dfs_2(0);
    cout<<total<<endl;
    return 0;
}


回溯,非递归求解

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
#define MAX 100

int is(int* c,int k)
{
    int i;
    for(i=1;i<k;i++)
        if(c[k]==c[i]||abs(i-k)==abs(c[k]-c[i]))
          return 0;
    return 1;
}


int main()
{
    int c[MAX];
    int N,i,j,k,case_=1;
    scanf("%d",&N); // N皇后

    for(j=1;j<=N;j++)//初始化
        c[j]=0;

    i=1;
    while(i>=1){
        c[i]=c[i]+1;
        while(c[i]<=N&&!is(c,i))
            c[i]=c[i]+1;

        if(i==N&&c[i]<=N){// 找到
            printf("Case %d:",case_++);
            for(j=1;j<=N;j++)
                printf("% d",c[j]);
            puts("");
        }

        if(i<=N&&c[i]<=N){
            i+=1;
        }
        else{
            c[i]=0;
            i=i-1;
        }
    }

    return 0;
}



八皇后

标签:回溯   递归   

原文地址:http://blog.csdn.net/u014705854/article/details/46611039

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!