zoukankan      html  css  js  c++  java
  • DFS+BFS(广度优先搜索弥补深度优先搜索遍历漏洞求合格条件总数)--09--DFS+BFS--蓝桥杯剪邮票

    题目描述

    如下图, 有12张连在一起的12生肖的邮票。现在你要从中剪下5张来,要求必须是连着的。(仅仅连接一个角不算相连) 
     
    比如,下面两张图中,粉红色所示部分就是合格的剪取。 
     
    请你计算,一共有多少种不同的剪取方法。 

    输出

    请填写表示方案数目的整数。 
     
    分析1
              使用开锁解锁机制、通过DFS一边搜索一边计数,每积累5个方格就停止进一步搜索,同时将结果存储起来。
       但是3、5、6、7、10(如图)此种情况是DFS做不到的,以下代码只用了DFS,只能得到82种结果。
     1 #include <iostream>
     2 #include <vector>
     3 #include <stdio.h>
     4 #include <queue>
     5 #include <cmath>
     6 #include <algorithm>
     7 using namespace std;
     8 const int ROW = 3;
     9 const int COL = 4;
    10 int sum = 0;
    11 int num = 0;
    12 int dd[4][2] = {{0,1},{1,0},{0,-1},{-1,0}};
    13 vector<vector<int> >a(ROW,vector<int>(COL,-1));
    14 vector<int>sig[10000];
    15 vector<int>zz;
    16 vector<int>temp;
    17 void rightload(){
    18     sig[sum] = temp;
    19 }
    20 bool checkrightload(){
    21     temp = zz;
    22     sort(temp.begin(),temp.end());
    23     for(int i = 0;i < sum;i++){
    24         if(sig[i] == temp)
    25             return false;
    26     }
    27     return true;
    28 }
    29 void lock(int i,int j){
    30     num++;
    31     a[i][j] = i*COL+j;
    32     zz.push_back(a[i][j]);
    33 }
    34 void unlock(int i,int j){
    35     num--;
    36     a[i][j] = -1;
    37     zz.pop_back();
    38 }
    39 void dfs(int i,int j){
    40     for(int zz = 0;zz < 4;zz++){
    41         int ii = i + dd[zz][0];
    42         int jj = j + dd[zz][1];
    43         if(ii < 0||jj < 0||ii >= ROW||jj >= COL)
    44             continue;
    45         if(a[ii][jj] == -1){
    46             lock(ii,jj);
    47             if(num == 5){
    48                 if(checkrightload()){
    49                     rightload();
    50                     sum++;
    51                 }
    52             }
    53             else
    54                 dfs(ii,jj);
    55             unlock(ii,jj);
    56         }
    57     }
    58 }
    59 int main(){
    60     for(int i = 0;i < ROW;i++){
    61         for(int j = 0;j < COL;j++){
    62             lock(i,j);
    63             dfs(i,j);
    64             unlock(i,j);
    65         }
    66     }
    67     for(int i = 0;i < sum;i++){
    68         for(int j = 0 ;j < 5;j++){
    69             cout <<sig[i][j] <<" ";
    70         }
    71         cout <<endl;
    72     }
    73     cout << sum <<endl;
    74     return 0;
    75 }

     分析2

        为了弥补分析1所提出的漏洞,需要用BFS与DFS相结合,才能得到所有情况,以下是BFS与DFS结合解题的代码。

      1 #include <iostream>
      2 #include <vector>
      3 #include <stdio.h>
      4 #include <queue>
      5 #include <cmath>
      6 #include <algorithm>
      7 using namespace std;
      8 const int ROW = 3;
      9 const int COL = 4;
     10 int sum = 0;
     11 int num = 0;
     12 int dd[4][2] = {{0,1},{1,0},{0,-1},{-1,0}};
     13 vector<vector<int> >a(ROW,vector<int>(COL,-1));
     14 vector<int>sig[10000];
     15 vector<int>zz;
     16 vector<int>temp;
     17 queue<pair<int,int> >myque;
     18 void rightload(){
     19     sig[sum] = temp;
     20 }
     21 bool checkrightload(){
     22     temp = zz;
     23     sort(temp.begin(),temp.end());
     24     for(int i = 0;i < sum;i++){
     25         if(sig[i] == temp)
     26             return false;
     27     }
     28     return true;
     29 }
     30 void lock(int i,int j){
     31     num++;
     32     a[i][j] = i*COL+j;
     33     zz.push_back(a[i][j]);
     34 }
     35 void unlock(int i,int j){
     36     num--;
     37     a[i][j] = -1;
     38     zz.pop_back();
     39 }
     40 void bfs(int i,int j){
     41     for(int zz = 4;zz >= 0;zz--){
     42         int ii = i + dd[zz][0];
     43         int jj = j + dd[zz][1];
     44         if(ii < 0||jj < 0||ii >= ROW||jj >= COL)
     45             continue;
     46         if(a[ii][jj] == -1){
     47             myque.push({ii,jj});
     48         }
     49     }
     50     while(!myque.empty()){
     51         int ii = myque.front().first;
     52         int jj = myque.front().second;
     53         myque.pop();
     54         lock(ii,jj);
     55         if(num == 5){
     56             if(checkrightload()){
     57                 rightload();
     58                 sum++;
     59             }
     60         }
     61         else{
     62             bfs(ii,jj);
     63         }
     64         unlock(ii,jj);
     65     }
     66 }
     67 void dfs(int i,int j){
     68     for(int zz = 0;zz < 4;zz++){
     69         int ii = i + dd[zz][0];
     70         int jj = j + dd[zz][1];
     71         if(ii < 0||jj < 0||ii >= ROW||jj >= COL)
     72             continue;
     73         if(a[ii][jj] == -1){
     74             lock(ii,jj);
     75             if(num == 5){
     76                 if(checkrightload()){
     77                     rightload();
     78                     sum++;
     79                 }
     80             }
     81             else{
     82                 dfs(ii,jj);
     83             }
     84             bfs(i,j);
     85             unlock(ii,jj);
     86         }
     87     }
     88 }
     89 int main(){
     90     for(int i = 0;i < ROW;i++){
     91         for(int j = 0;j < COL;j++){
     92             lock(i,j);
     93             dfs(i,j);
     94             unlock(i,j);
     95         }
     96     }
     97     for(int i = 0;i < sum;i++){
     98         for(int j = 0 ;j < 5;j++){
     99             cout <<sig[i][j] <<" ";
    100         }
    101         cout <<endl;
    102     }
    103     cout << sum <<endl;
    104     return 0;
    105 }
  • 相关阅读:
    win10如何在局域网中设置一台电脑的固定ip地址
    智能电视软件安装(WIFI上网)
    路由器连接宽带(成功上网步骤方法)
    FastReport.Net使用:[5]主从表
    FastReport.Net使用:[4]分组
    FastReport.Net使用:[3]简单报表一
    FastReport.Net使用:[2]添加MSSQL数据源一
    FastReport.Net使用:[1]屏蔽打印对话框
    如何配置FastReport.Net环境
    如何安装使用FastReport
  • 原文地址:https://www.cnblogs.com/qinqin-me/p/12260481.html
Copyright © 2011-2022 走看看