文章目录
17. 小主教问题
成绩: 10 / 折扣: 0.8
背景:
小主教问题是一个在正方格板上玩的国际象棋游戏。一个主教只可以在当前位置的对角线上移动。如果一个主教处在另一主教的对角线上,那么两个主教就会相互攻击。在下面的图中,深色的方格表示主教B1 可以达到的位置。图中还说明主教B1 和主教B2 处在相互攻击的位置上,而主教B1和主教B3彼此不会攻击,而且主教B2和主教B3也不处在相互攻击的位置上。
假设给定两个数n和k,现在需要确定把k个主教放在n × n大小的棋盘上,且任意两个主教都不会发生相互攻击,那么请编程算出共有多少种可能的放置方法。
输入:
输入可能包含多组测试用例。每组测试用例占一行,且包含两个整数n(1<=n<=8)和k(0 <= k <= n2)。
如果测试用例包含两个数字零,则表示终止输入,且不需处理此次输入。
输出:
对应每组测试输入有一个表示解决放置方法总数量的输出。此数值不大于1015。
来源:
#include<stdio.h> #include<math.h> #define max 100 double counter=0; static int m1[max]={0},m2[max]={0}; int n,k,t=0; void build(int c,int x,int y); void main() { while(scanf("%d%d",&n,&k)&&(n!=0||k!=0)) { if(k>=n*2-1) { if(k==1&&n==1) printf("1\n"); else printf("0\n"); } else {build(0,0,0); printf("%.0lf\n",counter); counter=0; } } } void build(int c,int x,int y) { int i,j; if(c==k) counter++; else { j=y; for(i=x;i<n;i++) { if(i!=x) j=0; for(;j<n;j++) { if(m1[i+j]==0&&m2[n-j+i-1]==0) { m1[i+j]=1; m2[n-j+i-1]=1; build(c+1,i,j); m1[i+j]=0; m2[n-j+i-1]=0; } } } } return ; }