题目描述:
如【图1.jpg】, 有12张连在一起的12生肖的邮票。
现在你要从中剪下5张来,要求必须是连着的。
(仅仅连接一个角不算相连)
比如,【图2.jpg】,【图3.jpg】中,粉红色所示部分就是合格的剪取。
请你计算,一共有多少种不同的剪取方法。
请填写表示方案数目的整数。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。
题目答案:
116
题目思路:
枚举五种数的所有组合然后判断这五个数是否连通即可。判断连通性可以用DFS来判断,上下左右四个方向可以将题目中的1,2,3,4,5,6,7,8,9,10数字进行转换,4和5是无法连通的,可以将其变为1,2,3,4,6,7,8,9,11,12,13,14如图,这样我就可以实现左右分别+1和-1,上下分别+5和-5来实现。
题目代码:
#include<cstdio>
#include<cstring>
using namespace std;
int dir[4] = {1,-1,5,-5};
int temp1[12] = {1,2,3,4,6,7,8,9,11,12,13,14};
int temp2[5];
int vis[5];
int ans = 0;
//dfs判断连通性
void dfs(int u){
for(int i=0 ;i<4 ;i++){
int t = temp2[u]+dir[i];
if(t>=1&&t<=14){
for(int j=0 ;j<5 ;j++)
if(t==temp2[j]&&!vis[j]){
vis[j]=1;
dfs(j);
}
}
}
}
int main(){
//枚举组合
for(int a=0 ;a<12 ;a++){
for(int b=a+1 ;b<12 ;b++){
for(int c=b+1 ;c<12 ;c++){
for(int d=c+1 ;d<12 ;d++){
for(int e=d+1 ;e<12 ;e++){
temp2[0]=temp1[a];
temp2[1]=temp1[b];
temp2[2]=temp1[c];
temp2[3]=temp1[d];
temp2[4]=temp1[e];
//初始化访问标记数组
memset(vis,0,sizeof(vis));
vis[0]=1;
dfs(0);
//连通性判断
int flag = 1;
for(int i=0 ;i<5 ;i++){
if(vis[i]==0){
flag = 0;
}
}
if(flag)ans++;
}
}
}
}
}
printf("%d\n",ans);
return 0;
}