剪邮票
如【图1.jpg】, 有12张连在一起的12生肖的邮票。
现在你要从中剪下5张来,要求必须是连着的。
(仅仅连接一个角不算相连)
比如,【图2.jpg】,【图3.jpg】中,粉红色所示部分就是合格的剪取。
请你计算,一共有多少种不同的剪取方法。
请填写表示方案数目的整数。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。
思路: 最好是先把所有的给方法给便利一遍,然后在判断是否联通,因为这样比较安全一点,到最后需要除以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);
}