蓝桥杯 剪邮票(bfs + dfs)

剪邮票

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

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

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

        图1                   图2                   图3

思路:1、首先从12数中选出5个数(求其所有组合数) 用dfs(保证五个数是递增的,避免重复) ,存入一维数组a中

   2、将a中的这五个数转化为二维坐标形式,然后将其在地图上置1(将vis置1),再用bfs判断地图上这5个置1的数是否相连

  1 #include<iostream> 
  2 #include<algorithm>
  3 #include<queue>
  4 #include<cstring>
  5 
  6 using namespace std;
  7 
  8 int a[100];
  9 int vis[4][5];    //下标为0的不用
 10 int dx[] = { 1,-1,0,0 };
 11 int dy[] = { 0,0,1,-1 };
 12 
 13 int result = 0;
 14 
 15 struct node
 16 {
 17     int x, y;
 18 }s;
 19 
 20 void bfs(int a[])
 21 {
 22     memset(vis, 0, sizeof(vis));   //记得将vis置零,防止有残余的1
 23     int x, y;
 24 
 25     //把一维下标转换为二维坐标
 26     for (int i = 1; i <= 5; ++i)
 27     {
 28         if (a[i] % 4 == 0)
 29         {
 30             x = a[i] / 4;
 31             y = 4;
 32         }
 33         else
 34         {
 35             x = a[i] / 4 + 1;
 36             y = a[i] % 4;
 37         }
 38         vis[x][y] = 1;
 39     }
 40 
 41     s.x = x;
 42     s.y = y;
 43 
 44     queue<node>Q;
 45     Q.push(s);
 46     vis[s.x][s.y] = 0;
 47     int num = 1;
 48 
 49     node t;
 50     while (!Q.empty())
 51     {
 52         t = Q.front();
 53         Q.pop();
 54         
 55         for (int i = 0; i < 4; ++i)
 56         {
 57             int xx = t.x + dx[i];
 58             int yy = t.y + dy[i];
 59             if (xx >= 1 && xx <= 3 && yy >= 1 && yy <= 4 && vis[xx][yy] == 1)
 60             {
 61                 ++num;    //每有一个相连,num就自增
 62                 vis[xx][yy] = 0;
 63                 s.x = xx;
 64                 s.y = yy;
 65                 Q.push(s);
 66             }
 67         }
 68     }
 69 
 70     if (num == 5)    //如果这5个数都相连    
 71     {
 72         ++result;
 73     }
 74 
 75 }
 76 
 77 void dfs(int step)  //从12个数中取出5个(即12取5的所有组合),存入一维数组a中(从下标1开始存储)
 78 {
 79     if (step == 6)
 80     {
 81         bfs(a);        //用bfs判断取出的这5个数在图中是否相连
 82         return;
 83     }
 84 
 85     for (int i = 1; i <= 12; ++i)
 86     {
 87         if (i > a[step - 1])    //以递增的顺序选出,可以防止重复
 88         {
 89             a[step] = i;
 90             dfs(step + 1);
 91         }
 92     }
 93 
 94     
 95 }
 96 
 97 int main()
 98 {
 99     memset(a, 0, sizeof(a));
100     dfs(1);
101     cout << result << endl;
102 
103     return 0;
104 }

猜你喜欢

转载自www.cnblogs.com/FengZeng666/p/10496223.html