剪邮票
如【图1.jpg】, 有12张连在一起的12生肖的邮票。
现在你要从中剪下5张来,要求必须是连着的。
(仅仅连接一个角不算相连)
比如,【图2.jpg】,【图3.jpg】中,粉红色所示部分就是合格的剪取。
请你计算,一共有多少种不同的剪取方法。
请填写表示方案数目的整数。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。
我们不一定使用dfs,可以使用二进制遍历:
#include <bits/stdc++.h>
using namespace std;
int maza[3][4];
int dir[][2]={0,1,0,-1,1,0,-1,0};
int vis[3][4]={0};
struct node{
int x,y;
};
int bfs(int x,int y){
memset(vis,0,sizeof vis);
int res=0;
queue<node>q;
node cur;
vis[x][y]=1;
cur.x=x,cur.y=y;
node nxt;
q.push(cur);
while(!q.empty()){
cur=q.front();
res++;
q.pop();
for(int i=0;i<4;i++){
int nx,ny;
nx=cur.x+dir[i][0];
ny=cur.y+dir[i][1];
if(nx>=0&&nx<3&&ny>=0&&ny<4&&!vis[nx][ny]&&maza[nx][ny]){
nxt.x=nx;
nxt.y=ny;
vis[nx][ny]=1;
q.push(nxt);
}
}
}
return res;
}
bool tran(int x){
memset(maza,0,sizeof maza);
int res=0;
int tx,ty;
for(int i=0;i<12;i++){
if((1<<i)&x){
int tempx=i/4;
int tempy=i%4;
tx=tempx;
ty=tempy;
maza[tempx][tempy]=1;
res++;
}
}
if(res!=5)return false;
else
{
if(bfs(tx,ty)==5){
for(int i=0;i<3;i++){
for(int j=0;j<4;j++)cout<<maza[i][j]<<" ";
cout<<endl;
}
cout<<endl<<endl;
return true;
}
else
return false;
}
}
int main()
{
int res=0;
for(int i=0;i<pow(2,12);i++){
if(tran(i)){
res++;
}
}
cout<<res<<endl;
return 0;
}