描述
在 n×n 的国际象棋棋盘上放置n个皇后,使得任何一个皇后都无法直接吃掉其他的皇后(任两个皇后都不能处于同一条横行、纵行或斜线上)
输入
输入有多组(直到-1结束)
每组一行 一个整数 n(0<n<11)代表皇后的个数。
输出
每组测试数据间输出一个换行。
对于每组数据,如果存在一个棋谱(使得n个皇后不会相互攻击),先输出这是第几种棋谱,然后输出该棋谱。当全部棋谱都输完时,最后输出该组总共摆放的棋谱数。
样例输入
1
2
4
-1
样例输出
case1:
1
There are 1 kinds of
There are 0 kinds of
case1:
0 1 0 0
0 0 0 1
1 0 0 0
0 0 1 0
case2:
0 0 1 0
1 0 0 0
0 0 0 1
0 1 0 0
There are 2 kinds of
提示
存放皇后时,按列优先的顺序从上往下从左至右的顺序遍历。
题意
在 n×n 的国际象棋棋盘上放置n个皇后,使得任何一个皇后都无法直接吃掉其他的皇后(任两个皇后都不能处于同一条横行、纵行或斜线上),输出所有可能的棋盘,最后输出总数
题解
回溯,往前试探一步,判断是否可行,再试探
代码
1 #include<stdio.h> 2 #include<string.h> 3 int n,k; 4 int pos[11];//pos[i]=j表示第i行的皇后在第j列 5 int abs(int x){return x>0?x:-x;} 6 bool st(int now) 7 { 8 for(int i=0;i<now;i++) 9 if(pos[i]==pos[now]||abs(pos[i]-pos[now])==abs(i-now))//和前几个在同一列,在同一斜 10 return false; 11 return true; 12 } 13 void print() 14 { 15 printf("case%d: ",++k);//k代表个数 16 for(int i=0;i<n;i++) 17 { 18 if(pos[i]==0) 19 printf("1"); 20 else 21 printf("0"); 22 for(int j=1;j<n;j++) 23 { 24 if(pos[i]==j) 25 printf(" 1"); 26 else 27 printf(" 0"); 28 } 29 puts(""); 30 } 31 } 32 void trail(int now)//递归回溯,now表示第几个试探 33 { 34 if(n==now)//填满n个结束 35 { 36 print(); 37 return; 38 } 39 for(int j=0;j<n;j++) 40 { 41 pos[now]=j;//先填上,试探 42 if(st(now))//可行就先选这个数 43 trail(now+1);//试探下一个 44 } 45 } 46 int main(){ 47 int o=0; 48 while(scanf("%d",&n)!=EOF,n!=-1) 49 { 50 if(o++)puts(""); 51 memset(pos,0,sizeof(pos)); 52 k=0; 53 trail(0); 54 printf("There are %d kinds of ",k); 55 } 56 return 0; 57 }