剪邮票
如【图1.jpg】, 有12张连在一起的12生肖的邮票。
现在你要从中剪下5张来,要求必须是连着的。(仅仅连接一个角不算相连)
比如,【图2.jpg】,【图3.jpg】中,粉红色所示部分就是合格的剪取。
请你计算,一共有多少种不同的剪取方法。
请填写表示方案数目的整数。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。
1.next_permutation+dfs
#include<bits/stdc++.h>
using namespace std;
int arr[]={0,0,0,0,0,0,0,1,1,1,1,1};//注意next_permutation是从小到大,生成下一个排列,所以int arr[]={1,1,1,1,1,0,0,0,0,0,0,0};就只会排列一次
int dx[]={-1,0,1,0};
int dy[]={0,1,0,-1};
int g[3][4];
void dfs(int i, int j)
{
g[i][j]=0;//0代表g[i][j]已经被遍历了,防止再次被遍历
for (int k = 0; k <4 ; ++k) {
int x=i+dx[k];
int y=j+dy[k];
if((g[x][y]==1)&&x<3&&y<4&&x>-1&&y>-1)
dfs(x,y);
}
}
int main()
{
int ans=0;
do{
int count=0;
for (int i = 0; i <3 ; ++i) {
for (int j = 0; j <4 ; ++j) {
g[i][j]=arr[j+i*4];//先把一维数组arr转为二维数组g
}
}
for (int i = 0; i <3 ; ++i) {
for (int j = 0; j <4 ; ++j) {
if(g[i][j]==1)//再从二维数组的每个邮票为起点开始遍历,如果邮票被选中(即g[i][j]==1)
{
dfs(i,j);//深度遍历,遍历完结果若g[i][j]中没有1,说明每张邮票都是连接的,count==1;否者count>1
count++;
}
}
}
if(count==1)
ans++;
}while(next_permutation(arr,arr+12));
printf("%d",ans);
}