剪邮票
如【图1.jpg】, 有12张连在一起的12生肖的邮票。
现在你要从中剪下5张来,要求必须是连着的。
(仅仅连接一个角不算相连)
比如,【图2.jpg】,【图3.jpg】中,粉红色所示部分就是合格的剪取。
请你计算,一共有多少种不同的剪取方法。
请填写表示方案数目的整数。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。
/**DFS+连通判断*/
/**注意 挑5个数时,不是排列问题,(12345,54321属于一种情况)*/
#include<stdio.h>
int num[6];
int visit[13];
int map[3][4];
int dirx[]={1,-1,0,0};
int diry[]={0,0,1,-1};
int count;
int ans=0;
void isTouch(int x,int y){
for(int i=0;i<4;i++){
int xx=x+dirx[i];
int yy=y+diry[i];
if(xx<0||xx>2||yy<0||yy>3)continue;
if(map[xx][yy]==1){
map[xx][yy]=0;
count++;
isTouch(xx,yy);
}
}
}
void judge(){
int x,y;
for(int i=1;i<6;i++){
x=(num[i]+3)/4-1;
y=num[i]%4;
if(y==0){
y=3;
}else{
y=y-1;
}
map[x][y]=1;
}
map[x][y]=0;
count=1;
isTouch(x,y);
if(count==5){
// for(int i=0;i<3;i++){
// for(int j=0;j<4;j++){
// printf("%d ",map[i][j]);
// }
// printf("\n");
// }
// printf("\n");
ans++;
}
}
void createNum(int n){
if(n==6){
for(int i=0;i<3;i++){
for(int j=0;j<4;j++){
map[i][j]=0;
}
}
judge();
return;
}
for(int i=num[n-1]+1;i<13;i++){
if(!visit[i]){
visit[i]=1;
num[n]=i;
createNum(n+1);
visit[i]=0;
}
}
}
int main(){
createNum(1);
printf("%d",ans);
return 0;
}