2016第七届蓝桥杯G剪邮票 (全排列+DFS)

【题目】

剪邮票

如【图1.jpg】, 有12张连在一起的12生肖的邮票。

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

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

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

【思路】

首先考虑剪任意五张邮票的问题,再考虑剪下来的这五张邮票是否连通。

①全排列:剪下任意五张邮票的所有可能;

1 int stamp[12]={0,0,0,0,0,0,0,1,1,1,1,1};//一共12张邮票,有五张要减下来 
2 int main(){
3     int key=0;
4     do{
5         if(check(stamp)) key++;
6     }while(next_permutation(stamp,stamp+12));//生成不同的全排列 
7     cout<<key; 
8 }

②编写check函数,判断五张邮票是不是连通的。首先要将1维数组转成二维数组。

 1 bool check(int stamp[12]){
 2     int t[3][4];
 3     int p=0;
 4     for(int i=0;i<3;i++){
 5         for(int j=0;j<4;j++){
 6             t[i][j]=stamp[p++];
 7         }
 8     }
 9     int cnt=0;
10     for(int i=0;i<3;i++){
11         for(int j=0;j<4;j++){
12             if(t[i][j]==1){//看要减下来的五张邮票能不能一遍走过 
13                 dfs(t,i,j);
14                 cnt++;
15             }
16         }
17     }
18     return cnt==1;
19 } 

③dfs算法

1 void dfs(int g[3][4],int i,int j){
2     g[i][j]=0;//已经走过标记为0 
3     if(i-1>=0&&g[i-1][j]==1) dfs(g,i-1,j);
4     if(i+1<=2&&g[i+1][j]==1) dfs(g,i+1,j);
5     if(j-1>=0&&g[i][j-1]==1) dfs(g,i,j-1);
6     if(j+1<=3&&g[i][j+1]==1) dfs(g,i,j+1);
7 }

完整代码(答案116)

 1 #include<bits/stdc++.h> 
 2 using namespace std;
 3 int stamp[12]={0,0,0,0,0,0,0,1,1,1,1,1};//一共12张邮票,有五张要减下来 
 4 
 5 void dfs(int g[3][4],int i,int j){
 6     g[i][j]=0;//已经走过标记为0 
 7     if(i-1>=0&&g[i-1][j]==1) dfs(g,i-1,j);
 8     if(i+1<=2&&g[i+1][j]==1) dfs(g,i+1,j);
 9     if(j-1>=0&&g[i][j-1]==1) dfs(g,i,j-1);
10     if(j+1<=3&&g[i][j+1]==1) dfs(g,i,j+1);
11 }
12 
13 bool check(int stamp[12]){
14     int t[3][4];
15     int p=0;
16     for(int i=0;i<3;i++){
17         for(int j=0;j<4;j++){
18             t[i][j]=stamp[p++];
19         }
20     }
21     int cnt=0;
22     for(int i=0;i<3;i++){
23         for(int j=0;j<4;j++){
24             if(t[i][j]==1){//看要减下来的五张邮票能不能一遍走过 
25                 dfs(t,i,j);
26                 cnt++;
27             }
28         }
29     }
30     return cnt==1;
31 } 
32 
33 int main(){
34     int key=0;
35     do{
36         if(check(stamp)) key++;
37     }while(next_permutation(stamp,stamp+12));//生成不同的全排列 
38     cout<<key; 
39 }

猜你喜欢

转载自www.cnblogs.com/taiga/p/12681057.html
今日推荐