如【图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。