蓝桥杯2016:剪邮票



剪邮票


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


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


请填写表示方案数目的整数。

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


#include
using namespace std;
int a[13]={0};
int b[5]={0};
int d[4][2]={-1,0,1,0,0,-1,0,1}; 
int sum=0;
void show(int a[3][4]){
for(int i=0;i<3;i++){
for(int j=0;j<4;j++)
cout<cout<}


cout< }
int check(int c[]){
int b[5];
int mat[3][4]={0};
int vis[3][4]={0};
for(int i=0;i<5;i++){
b[i]=c[i]-1;
mat[b[i]/4][b[i]%4]=1;//标记组合数在数组中的位置 
}


vis[b[0]/4][b[0]%4]=1;//标记从第一个开始 
for(int i=0;i<5;i++){//五个都顺序作为起点 
int x=b[i]/4;int y=b[i]%4;
if(vis[x][y]==1) {//看过的才能作为起始 
for(int j=0;j<4;j++){
int nx=x+d[j][0];
int ny=y+d[j][1];
if(nx>=0&&nx<=2&&ny>=0&&ny<=3)
if(mat[nx][ny]==1){
if(vis[nx][ny]!=1) i=-1;//每加入一个新标记,就重新扫描 
vis[nx][ny]=1;//将上下左右相连的且在组合中的都加入起点中 
}
}
}
}
for(int i=0;i<5;i++){
if(vis[b[i]/4][b[i]%4]!=1)return false;

return true;
}
int dfs(int arr[],int n,int k,int num,int index){//dfs求所有组合 n为总数,k为组合数,num为当前层数,index为组合头数字位置 

if(num==k){//找到了符合的组合数 
if(check(b)==true)sum++;//如果符合条件 
return 0;
}
for(int i=index;i<=n;i++){
if(a[i]==0){
a[i]=1;
b[num]=i;
dfs(arr,n,k,num+1,index);
a[i]=0;
}
index++;
}

}
int main(){
int n=12,k=5;
dfs(a,n,k,0,1);
cout<return 0;

你可能感兴趣的:(蓝桥杯)