Little Bishops

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Kaiyang_Shao/article/details/51318625

问题描述


A bishop is a piece used in the game of chess which is played on a board of square grids. A bishop can only move diagonally from its current position and two bishops attack each other if one is on the path of the other. In the following figure, the dark squares represent the reachable locations for bishop B1 form its current position.  The figure also shows that the bishops B1 and B2 are in attacking positions whereas B1 andB3 are not. B2 and B3 are also in non-attacking positions.

Now, given two numbers n and k, your job is to determine the number of ways one can put k bishops on an n × n chessboard so that no two of them are in attacking positions.

Input

The input file may contain multiple test cases. Each test case occupies a single line in the input file and contains two integers n(1 ≤ n ≤ 8) andk (0 ≤ k ≤ n2).

A test case containing two zeros for n and k terminates the input and you won't need to process this particular input.

Output

For each test case in the input print a line containing the total number of ways one can put the given number of bishops on a chessboard of the given size so that no two of them are in attacking positions. You may safely assume that this number will be less than 1015.


测试输入关于“测试输入”的帮助 期待的输出关于“期待的输出”的帮助 时间限制关于“时间限制”的帮助 内存限制关于“内存限制”的帮助 额外进程关于“{$a} 个额外进程”的帮助
测试用例 1 以文本方式显示
  1. 8 6↵
  2. 4 4↵
  3. 0 0↵
以文本方式显示
  1. 5599888↵
  2. 260↵
1秒 64M 0
题解思路

大致思路:

将棋盘旋转45度,然后就相当于相只可以横着或者竖着攻击,这样就跟八皇后的问题差不多,每次找到可以摆放的相的位置。然后就是一行一行的向下推,分别找到每一行可能存在的摆放情况,最后把白棋盘和黑棋盘的情况相乘就可以得到最终的结果。(白色的格子攻击不到黑色格子的相)

具体实现:

对于i行可以摆放相的位置有两种情况,一种情况是在前i-1行摆了j个相;另一种情况是在前i-1行摆了j-1个相,然后在i行摆一个相,那么在i行就可以有dp[i-1][j-1]*(c[i]-j+1)种情况。所以总和起来就是dp[i][j]=dp[i-1][j]+dp[i-1][j-1]*(c[i]-j+1),然后注意一下边界条件。

注意事项:

(1)黑白格子的行数想错1;

(2)计算每一行棋子的个数的时候需要注意,别计算错了。

摆放的相的个数应该不大于改行的棋盘个数。


实现代码


<span style="font-family:Microsoft YaHei;font-size:14px;">#include<stdio.h>  
#include<string.h>      
int dpblack[10][70], dpwrite[10][70]; 
int Black[10], Write[10];   
int main()  
{  
	long zong=0;
    int i,j,n,k,p;    
    while(scanf("%d%d",&n,&k)==2)  
    {  
    	if(n+k==0)
    	break;
    	zong=0;
    	memset(dpblack,0,sizeof(dpblack));
    	memset(dpwrite,0,sizeof(dpwrite));
        memset(Black,0,sizeof(Black));  
        memset(Write,0,sizeof(Write));  
        if(n==1)
        {
        	Black[1]=1;
        }
        if(n==2)
        {
        	Write[1]=2;
        	Black[1]=1;
        	Black[2]=1;
        }
        if(n==3)
        {
        	Write[1]=2;
        	Write[2]=2;
        	Black[1]=1;
        	Black[2]=1;
        	Black[3]=3;
        }
        if(n==4)
        {
        	Write[1]=2;
			Write[2]=2;
			Write[3]=4;	
			Black[1]=1;
			Black[2]=1;
			Black[3]=3;
			Black[4]=3;
			
        }
        if(n==5)
        {
        	Write[1]=2;
			Write[2]=2;
			Write[3]=4;
			Write[4]=4;
			Black[1]=1;
			Black[2]=1;
			Black[3]=3;
			Black[4]=3;
			Black[5]=5;
				
        }
        if(n==6)
        {
        	Write[1]=2;
			Write[2]=2;
			Write[3]=4;
			Write[4]=4;
			Write[5]=6;
			Black[1]=1;
			Black[2]=1;
			Black[3]=3;
			Black[4]=3;
			Black[5]=5;
			Black[6]=5;
			
				
        }
        if(n==7)
        {
        	Write[1]=2;
        	Write[2]=2;
        	Write[3]=4;
        	Write[4]=4;
        	Write[5]=6;
        	Write[6]=6;
        	Black[1]=1;
        	Black[2]=1;
        	Black[3]=3;
        	Black[4]=3;
        	Black[5]=5;
        	Black[6]=5;
        	Black[7]=7;
        	
        }
        if(n==8)
        {
        	Write[1]=2;
        	Write[2]=2;
        	Write[3]=4;
        	Write[4]=4;
        	Write[5]=6;
        	Write[6]=6;
        	Write[7]=8;
        	Black[1]=1;
        	Black[2]=1;
        	Black[3]=3;
        	Black[4]=3;
        	Black[5]=5;
        	Black[6]=5;
        	Black[7]=7;
        	Black[8]=7;
        	
        }  
	/*	for(p=0;p<10;p++)
		{
			printf("%d ",Write[p]);
		}	
		printf("\n");
		for(p=0;p<10;p++)
		{
			printf("%d ",Black[p]);
		}	
		printf("\n");*/	
	   // memset(dpblack,0,sizeof(dpblack));  
    	for(i=0;i<=n;i++)
		{
			 dpblack[i][0]=1;  	
		}  
    	for(i=1;i<=n;i++) 
		{
			for(j=1;j<=Black[i];j++)
			{
				dpblack[i][j]=dpblack[i-1][j]+dpblack[i-1][j-1]*(Black[i]-j+1);
			}
		}  
	//	memset(dpwrite,0,sizeof(dpwrite));  
    	for(i=0;i<=n;i++)
		{
			 dpwrite[i][0]=1;  	
		}  
    	for(i=1;i<=n;i++) 
		{
			for(j=1;j<=Write[i];j++)
			{
				dpwrite[i][j]=dpwrite[i-1][j]+dpwrite[i-1][j-1]*(Write[i]-j+1);
			}
		}   
        for (i=0;i<=k;i++)
		{
			zong+=dpblack[n][i]*dpwrite[n-1][k-i];
		}    
        printf("%ld\n",zong);  
    }  
    return 0;  
}</span>


猜你喜欢

转载自blog.csdn.net/Kaiyang_Shao/article/details/51318625
今日推荐