题目描述:
如【图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<bits/stdc++.h> using namespace std; int chess[4][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}}; int a,b,c,d,e; int array[5]; int vis[100]; //vis数组标记这个五个数 int book[10][10]; //book数组标记图 int next[4][2]={{1,0},{-1,0},{0,1},{0,-1}}; void dfs(int x,int y) { int i,j; int tx,ty; for(i=0;i<4;i++) { tx=x+next[i][0]; ty=y+next[i][1]; if(tx<0 || tx>=3 || ty<0 || ty>=4) continue; for(j=0;j<5;j++) { if(vis[array[j]]==0 && chess[tx][ty]==array[j] && book[tx][ty]==0) { vis[array[j]]=1; book[tx][ty]=1; dfs(tx,ty); book[tx][ty]=0; //这句加不加无所谓 } } book[tx][ty]=1; } } int main() { int i; int sum=0; for(a=1;a<=12;a++) for(b=a+1;b<=12;b++) for(c=b+1;c<=12;c++) for(d=c+1;d<=12;d++) for(e=d+1;e<=12;e++) { array[0]=a; array[1]=b; array[2]=c; array[3]=d; array[4]=e; memset(vis,0,sizeof(vis)); memset(book,0,sizeof(book)); vis[a]=1; book[((a-1) - (a-1)%4)/4][(a-1)%4]=1; dfs(((a-1) - (a-1)%4)/4 , (a-1)%4 ); int flag=0; for(i=0;i<5;i++) { if(vis[array[i]]==0) { flag=1; break; } } if(flag==0) sum++; } printf("%d\n",sum); return 0; }