剪邮票

如【图1.jpg】, 有12张连在一起的12生肖的邮票。
现在你要从中剪下5张来,要求必须是连着的。
(仅仅连接一个角不算相连)
比如,【图2.jpg】,【图3.jpg】中,粉红色所示部分就是合格的剪取。
 

请你计算,一共有多少种不同的剪取方法。

我的想法是这样的,先用十三个数里面拿出五个数,用回溯的方法,然后再判断这五个数的形态:

再十二个数中剪出五个,只能有三种形态:1,五个相连的(比如1 2 3 4 5),2四个相连,然后一个被孤立的(比如 1 2 3 4 9),3,一个边是三个相连,一边是两个相连(比如1 2 3 9 10),然后我们要求是要算出五个相连的,然后找到和其他的不同点,这时候我就发现,五个相连的话,必定会有四个结合点(比如上面(1-2,2-3,3=4,1-5)),其他两种情况的话就只有三个结合点(比如第二(1-2,2-3,3-4),第三个(1-2,2-3,9-10)),所以可以从这下手解决,代码实现如下:

 

#include<stdio.h>
int a[13]={0},b[5];
long int count=0;
int key;
int fun2(int n)
{
	int i,j=1;
	if(n==1)
	{
		for(i=0;i<5;i++)
		{
			if(b[i]==2||b[i]==5)
			{
				j=0;
				key++;
			}
		}
	}
	if(n==2)
	{
		for(i=0;i<5;i++)
		{
			if(b[i]==1||b[i]==3||b[i]==6)
			{
				j=0;
				key++;
			}
		}
	}
	if(n==3)
	{
		for(i=0;i<5;i++)
		{
			if(b[i]==2||b[i]==4||b[i]==7)
			{
				j=0;
				key++;
			}
		}
	}
	if(n==4)
	{
		for(i=0;i<5;i++)
		{
			if(b[i]==3||b[i]==8)
			{
				j=0;
				key++;
			}
		}
	}
	if(n==5)
	{
		for(i=0;i<5;i++)
		{
			if(b[i]==1||b[i]==6||b[i]==9)
			{
				j=0;
				key++;
			}
		}
	}
	if(n==6)
	{
		for(i=0;i<5;i++)
		{
			if(b[i]==2||b[i]==5||b[i]==7||b[i]==10)
			{
				j=0;
				key++;
			}
		}
	}
	if(n==7)
	{
		for(i=0;i<5;i++)
		{
			if(b[i]==3||b[i]==6||b[i]==8||b[i]==11)
			{
				j=0;
				key++;
			}
		}
	}
	if(n==8)
	{
		for(i=0;i<5;i++)
		{
			if(b[i]==4||b[i]==7||b[i]==12)
			{
				j=0;
				key++;
			}
		}
	}
	if(n==9)
	{
		for(i=0;i<5;i++)
		{
			if(b[i]==5||b[i]==10)
			{
				j=0;
				key++;
			}
		}
	}
	if(n==10)
	{
		for(i=0;i<5;i++)
		{
			if(b[i]==6||b[i]==9||b[i]==11)
			{
				j=0;
				key++;
			}
		}
	}
	if(n==11)
	{
		for(i=0;i<5;i++)
		{
			if(b[i]==7||b[i]==10||b[i]==12)
			{
				j=0;
				key++;
			}
		}
	}
	if(n==12)
	{
		for(i=0;i<5;i++)
		{
			if(b[i]==8||b[i]==11)
			{
				j=0;
				key++;
			}
		}
	}
	return j;
}
void fun(int n)
{
	int i;
	if(n==5)
	{
		key=0;
		for(i=0;i<5;i++)
		{
			if(fun2(b[i])==1)return;
		}
		if(key!=6)
		count++;
		return;
	}
	for(i=1;i<13;i++)
	{
		if(a[i]==0)
		{
			a[i]=1;
			b[n]=i;
			fun(n+1);
			a[i]=0;
		}
	}
}
int main()
{
	fun(0);
	printf("%ld",count/120);
	return 0;
}

答案是116。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值