• 蓝桥杯 剪邮票(dfs枚举 + bfs)


    剪邮票

    如图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 }
  • 相关阅读:
    CruiseControl.NET 三言两语
    在MFC程序中增加控制台
    VS2005 编译Release版本出现清单文件的错误
    内存泄露问题
    软件设计原则
    boost::shared_ptr 分析与实现
    corelDraw 的CDR格式解析
    13. 量词操作符—【LINQ标准查询操作符】
    SQL SERVER执行查询的顺序
    CSLA命令对象的简单封装
  • 原文地址:https://www.cnblogs.com/FengZeng666/p/10496223.html
Copyright © 2020-2023  润新知