Sgu 224
此题可用位运算优化的搜索算法来做,主要参考M67牛的位运算教程:http://www.matrix67.com/blog/archives/266
主要思想是设置3个参数row,ld,rd分别代表纵列,主对角线和副对角线上的禁位情况,此题与n皇后问题稍有不同,是在n*n的棋盘上放置k个,所以需要稍稍修改,详见程序。
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
1 #include<stdio.h>
2 #include<stdlib.h>
3 int upperlim,sum,n,k;
4 void test(int row,int ld,int rd,int cnt,int now)
5 {
6 if(now>n) return;
7 int pos,p;
8 if(cnt<k)
9 {
10 pos=(upperlim)&(~(row|ld|rd));
11 while(pos!=0)
12 {
13 p=pos&(-pos);
14 pos=pos-p;
15 test(row+p,(ld+p)<<1,(rd+p)>>1,cnt+1,now+1);
16 }
17 test(row,ld<<1,rd>>1,cnt,now+1); // 这是添加的地方!
18 }
19 else ++sum;
20 }
21 int main()
22 {
23 int a[14]={},i,j;
24 scanf("%d%d",&n,&k);
25 upperlim=(1<<n)-1;
26 test(0,0,0,0,0);
27 printf("%d\n",sum);
28 return 0;
29 }
2 #include<stdlib.h>
3 int upperlim,sum,n,k;
4 void test(int row,int ld,int rd,int cnt,int now)
5 {
6 if(now>n) return;
7 int pos,p;
8 if(cnt<k)
9 {
10 pos=(upperlim)&(~(row|ld|rd));
11 while(pos!=0)
12 {
13 p=pos&(-pos);
14 pos=pos-p;
15 test(row+p,(ld+p)<<1,(rd+p)>>1,cnt+1,now+1);
16 }
17 test(row,ld<<1,rd>>1,cnt,now+1); // 这是添加的地方!
18 }
19 else ++sum;
20 }
21 int main()
22 {
23 int a[14]={},i,j;
24 scanf("%d%d",&n,&k);
25 upperlim=(1<<n)-1;
26 test(0,0,0,0,0);
27 printf("%d\n",sum);
28 return 0;
29 }