如【图1.jpg】, 有12张连在一起的12生肖的邮票。
现在你要从中剪下5张来,要求必须是连着的。
(仅仅连接一个角不算相连) 比如,【图2.jpg】,【图3.jpg】中,粉红色所示部分就是合格的剪取。
请你计算,一共有多少种不同的剪取方法。
【最终结果】
116
思路
1.首先从12个数里面取出5个数来
2.把这五个数保存在mpt[3][4]当中,是这五个数的位置用1表示,不是的用0表示
3.判断这五个数是否相连
4.用深度遍历的方法判断。
#include <iostream> #include <string> using namespace std; int sum = 0; int a[12] = {1,2,3,4,5,6,7,8,9,10,11,12}; int mpt[3][4]; int mpt_cmd[3][4]; int b[5];//保存取出来的五个元素 int count = 0; int mect[4][2] = {1,0,-1,0,0,1,0,-1}; void Print() { for(int i=0;i<3;i++) { for(int j=0;j<4;j++) { cout<<mpt[i][j]<<" "; } cout<<endl; } cout<<endl; cout<<endl; } int Hand(int x,int y)//判断mpt[x][y],是否在mpt_cmd中,在里面返回0,不在返回1; { if(mpt[x][y] == mpt_cmd[x][y]) { return 0; } return 1; } void Lianjie(int x,int y)//判断五个数是否连接 { int x1,y1; for(int i=0;i<4;i++)//有四个方向 { x1 = x+mect[i][0]; y1 = y+mect[i][1]; if(x1<0||x1>=3||y1<0||y1>=4)//超出界限了 continue; if((mpt[x1][y1] == 0)|| (Hand(x1,y1) == 0))//该点不是所抽的五个数,或者该点已经遍历过 continue; mpt_cmd[x1][y1] = 1; count++; Lianjie(x1,y1); } } void Add()//抽取的五个数 { count = 0; memset(mpt,0,sizeof(mpt));//把数组初始化为0; memset(mpt_cmd,0,sizeof(mpt_cmd)); int x,y; for(int i=0;i<5;i++)//将抽出来的五个数保存到数组mpt中,另该出为1,其它处为零 { x = (b[i]-1)/4; y = (b[i]-1)%4; mpt[x][y] = 1; } count =1; Lianjie(x,y);//从保存的最后一个数当起点 if(count==6) { //Print();输出每一种情况 sum++; } } void fun(int m,int n) { int i; for(i=m;i>=n;i--) { b[n-1] = a[i-1]; if(n>1) fun(i-1,n-1); else { Add(); } } } int main() { fun(12,5); cout<<sum++<<endl; return 0; }