X-man

导航

hdu 2553 N皇后问题(一维数组详尽解释)

//一维数组解法(注释详尽)
//num皇后可以表示第num列,然后枚举num皇后所在的行
//二维数组对角线转换为坐标的关系
#include<stdio.h> #include<string.h> int map[15],hang[15],ans[15]; int n,cnt; void Dfs(int num) { int i,j,k; if(num>n) { cnt++; return ; } for(i=1;i<=n;i++) { map[num]=i;//第num的皇后在第num列i行 if(!hang[i])//枚举第i行是否可行 { for(j=1;j<num;j++)//枚举前num-1个皇后 {//num就代表列,map[num]就代表num所在的行 if(map[num]-num==map[j]-j||map[num]+num==map[j]+j) break; } if(j==num) { hang[i]=1; Dfs(num+1); hang[i]=0; } } } } int main() { int m; for(n=1; n<11; n++) { memset(hang,0,sizeof(hang)); memset(map,0,sizeof(map)); cnt=0; Dfs(1); ans[n]=cnt; } while(scanf("%d",&m)!=EOF&&m) { printf("%d\n",ans[m]); } return 0; }

 

单纯二维坐标做法:

 

#include <stdio.h>
#include <string.h>
int count[15];//n的最大范围是10,打表!
int k,cal;//k个大小的棋盘放的数目
int map[15][15];//棋盘
int dfs(int row,int column)
{
    //最后一行也合适,放置数目加1
    if(row>k)
    {
        cal++;
        return 1;
    }
    //判断同一列是否有棋子
    for(int i=1; i<row; i++)
        if(map[i][column])
            return 0;
    //判断左上45度是否有棋子
    for(int i=row-1,j=column-1; i>0&&j>0; i--,j--)
        if(map[i][j])
            return 0;
    //判断右上45度是否有棋子
    for(int i=row-1,j=column+1; i>0&&j<=k; i--,j++)
        if(map[i][j])
            return 0;
    //都通过,该点合适并判断下一行
    map[row][column]=1;
    for(int i=1; i<=k; i++)
    {
        //当dfs(row+1,i,k)为1时,改行为最后一行,棋盘已放满
        if(dfs(row+1,i))
            break;
    }
    map[row][column]=0;
    //该点判断完成,恢复后再去判断其他点
    return 0;
}
int main()
{
    int n;
    for(k=1; k<=10; k++)
    {
        memset(map,0,sizeof(map));
        cal=0;
        //count[k]=0;
        for(int i=1; i<=k; i++)
        dfs(1,i);
        count[k]=cal;
    }
    while(scanf("%d",&n)!=EOF&&n)
        printf("%d\n",count[n]);
    return 0;
}
View Code

 

posted on 2013-09-20 21:12  雨钝风轻  阅读(374)  评论(0编辑  收藏  举报