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