如【图1.jpg】, 有12张连在一起的12生肖的邮票。
现在你要从中剪下5张来,要求必须是连着的。
(仅仅连接一个角不算相连)
比如,【图2.jpg】,【图3.jpg】中,粉红色所示部分就是合格的剪取。
请你计算,一共有多少种不同的剪取方法。
请填写表示方案数目的整数。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。
思路在注释里,一开始做这题的时候感觉很困难,没理解题目的意思,把邮票的形状也考虑在约束范围内,所以很尴尬的错了
#include <stdio.h>
#include <stdbool.h>
#define M 5
bool check();
void dfs(bool *judge,int i);
int num[M]={0},count=0;
int main(void)
{
//暴力破解,对五张邮票的位置进行试探,加上剪枝
for(num[0]=0;num[0]<12;num[0]++)
for(num[1]=num[0]+1;num[1]<12;num[1]++)
if(num[0]!=num[1])
for(num[2]=num[1]+1;num[2]<12;num[2]++)
if(num[0]!=num[2]&&num[1]!=num[2])
for(num[3]=num[2]+1;num[3]<12;num[3]++)
if(num[0]!=num[3]&&num[1]!=num[3]&&num[2]!=num[3])
for(num[4]=num[3]+1;num[4]<12;num[4]++)
if(num[0]!=num[4]&&num[1]!=num[4]&&num[2]!=num[4]&&num[3]!=num[4])
if(check())
count++;
printf("%d\n",count);
return 0;
}
bool check() //检查函数,如果judge数组里元素全为true,则返回true
{
bool judge[M];
int i=0;
for(i=0;i<M;i++) judge[i] = false;
dfs(judge,0);
for(i=0;i<M;i++)
{
if(!judge[i]) return false;
}
return true;
}
void dfs(bool *judge,int i) //判断num数组的值,如果num数组的j位与i位的关系符合条件,则judge的j位赋值位true
{
int j=0;
judge[i] = true;
for(j=0;j<M;j++)
{
if(!judge[j]&&(num[j]/4==num[i]/4)&&(num[j]==num[i]-1||num[i]==num[j]-1))
dfs(judge,j);
else if(!judge[j]&&(num[j]+4==num[i]||num[i]+4==num[j]))
dfs(judge,j);
}
}