剪邮票

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

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

请填写表示方案数目的整数。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。

蓝桥杯 剪邮票 C语言,已输出

蓝桥杯 剪邮票 C语言,已输出

蓝桥杯 剪邮票 C语言,已输出

 

 

思路: 最好是先把所有的给方法给便利一遍,然后在判断是否联通,因为这样比较安全一点,到最后需要除以120

因为5! 是120, 也可以不用除以,120,

方法:每一个数的位置必定比他前面的数要大,所以我们只需要,在便利12个位置的时候,比上一个位置大就行了,这样就不需要,除以120,这个题判断是否联通是个重点,所以请好好看一下,判断是否联通的拿个函数

 

也可以,每次判断是否联通,但是这样,等到了5的时候成功,但这个方法我还没有写出来。。。。,比较麻烦,会有的地方判断不出来,所以结果是64,是错的,

正确答案在下面这个代码里,可以复制一下看看

 

 

我本来写这个就是没写对,原因就是判断是否联通的地方出了错,怎样安全,怎样写,尽量

水平有限,见谅

 

 

 

下面是代码

#include<stdio.h>
int a[13]={0}; 
int b[13]={0};
int count = 0,F;
int bfs(int n,int i)//重要的是这个,判断是否五个相连通 
{
	a[i] = 0;
	if(F != 4)
	{
		if(i - 1 >= 0 && (i - 1) % 4 != 3 && a[i-1] == 1)
		{
			F++;
			bfs(n+1,i-1);
		}
		if(i + 1 < 12 && (i + 1) % 4 != 0 && a[i+1] == 1)
		{
			F++;
			bfs(n+1,i+1);
		}
		if(i - 4 >= 0 && a[i-4] == 1)
		{
			F++;
			bfs(n+1,i-4);
		}
		if(i + 4 < 12 && a[i+4] == 1)
		{
			F++;
			bfs(n+1,i+4);
		}
	}
}
int printff(int k)
{
		int i;
		
		F = 0;
		for(i = 11; i >= 0; i--){//赋值给 a 数组 
			a[i] = b[i];
		}
		
		bfs(0,k);//调用函数,判断是否五个相连通 
		
		if(F == 4){
			
			printf("第%d个\n",++count);
			
			for(i = 0; i < 12; i++){
				printf("%d ",b[i]);
				if(i % 4 == 3)printf("\n");
			}
			
			printf("\n");
		}
}
int f(int k,int n)
{
	int i,j;
	if(n == 5)//如果已经选择了有5个 
	{
		printff(k);//进入测试,看是否满足联通 
	}
	else
	for(i = k; i < 12 ;i++)//这里相当于是一个剪枝吗?,避免了重复
	{
		if(b[i] == 0)
		{
			b[i] = 1;
				f(i,n+1);
			b[i] = 0;
		}
	}
}
int main()
{
	f(0,0);
}

 

相关文章: