题目描述:
如【图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; }