蓝桥:剪邮票

剪邮票

如【图1.jpg】,
蓝桥:剪邮票

有12张连在一起的12生肖的邮票。
现在你要从中剪下5张来,要求必须是连着的。
(仅仅连接一个角不算相连)
比如,【图2.jpg】,【图3.jpg】中,粉红色所示部分就是合格的剪取。
蓝桥:剪邮票
蓝桥:剪邮票

请你计算,一共有多少种不同的剪取方法。

请填写表示方案数目的整数。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字

 思路 : 枚举格子,BFS判断连通。

#include<iostream>
#include<queue>
#include<cstring>
using namespace std;
int   mp[4][5];
int   num[7];
int   dir[4][2] ={ {0,1},{0,-1},{-1,0},{1,0}};
int   vis[4][5];
struct Node{
	   int x,y;
}node;

int    changexy( int n ){
	   for( int i=1;i<=3;i++){
	   	    for( int j=1;j<=4;j++){
	   	    	 if( mp[i][j] == n )
	   	    	     return i;
			   }
	   }
}
bool  change( ){
	  memset(vis,0,sizeof(vis));
	  int x,y;
	  for( int i=1;i<=5;i++){
	       x = changexy( num[i] );
		   y = num[i] - (x-1)*4;
		   vis[x][y] = 1 ; 
	  }
        
	  node.x=x;
	  node.y=y;
	  queue< struct Node > q;
	  q.push( node );
	  vis[x][y] =  0; 
	  while( !q.empty() ){
	  	   node = q.front();
	  	   q.pop();
	  	   x = node.x;
	  	   y = node.y; 
		   for( int i=0;i<=3;i++){
	  	   	    node.x = x + dir[i][0];
				node.y = y + dir[i][1]; 
				 
			    if( node.x>=1 && node.x<=3 && node.y>=1&&node.y<=4 && vis[node.x][node.y]){
	  	            vis[node.x][node.y] = 0; 
			   	    q.push(node); 
			  } 	    
			 } 
	  } 
	 
	  for( int i=1;i<=3;i++){
	  	   for( int j=1;j<=4;j++){
	  	   	    if( vis[i][j] ==1)
	  	   	        return false;
			 }
	  }        	  
	  return true;
}
int   main(void){
	  
	  int cnt=0;
	  for( int i=1;i<=3;i++){
	  	 for( int j=1;j<=4;j++){
	  	 	  mp[i][j]=++cnt;
		   }
	  }
	  int ans=0;
	  for(  num[1]=1;num[1]<=8;num[1]++){
	  	  
	  for(  num[2]=num[1]+1;num[2]<=9;num[2]++){
	  
	  for(  num[3]=num[2]+1;num[3]<=10;num[3]++){
	  
	  for(  num[4]=num[3]+1;num[4]<=11;num[4]++){
	  
	  for(  num[5]=num[4]+1;num[5]<=12;num[5]++){
	  	    if( change() )
	  	        ans++;  
	  }	
	  }	
	  }	
	  } 
	  }
    printf("%d\n",ans);
   	return 0;
}