现在的位置: 首页 > 综合 > 正文

小主教问题

2012年01月13日 ⁄ 综合 ⁄ 共 934字 ⁄ 字号 评论关闭
文章目录
 

17. 小主教问题

成绩: 10 / 折扣: 0.8

背景:

小主教问题是一个在正方格板上玩的国际象棋游戏。一个主教只可以在当前位置的对角线上移动。如果一个主教处在另一主教的对角线上,那么两个主教就会相互攻击。在下面的图中,深色的方格表示主教B1 可以达到的位置。图中还说明主教B1 和主教B2 处在相互攻击的位置上,而主教B1和主教B3彼此不会攻击,而且主教B2和主教B3也不处在相互攻击的位置上。

假设给定两个数nk,现在需要确定把k个主教放在n × n大小的棋盘上,且任意两个主教都不会发生相互攻击,那么请编程算出共有多少种可能的放置方法。

输入:

输入可能包含多组测试用例。每组测试用例占一行,且包含两个整数n(1<=n<=8)k(0 <= k <= n2

如果测试用例包含两个数字零,则表示终止输入,且不需处理此次输入。

输出:

对应每组测试输入有一个表示解决放置方法总数量的输出。此数值不大于1015

来源:

http://acm.uva.es/p/v8/861.html

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

抱歉!评论已关闭.