DFS+BFS(廣度優先搜索彌補深度優先搜索遍歷漏洞求合格條件總數)--09--DFS+BFS--藍橋杯剪郵票

題目描述

以下圖, 有12張連在一塊兒的12生肖的郵票。如今你要從中剪下5張來,要求必須是連着的。(僅僅鏈接一個角不算相連) 
 
好比,下面兩張圖中,粉紅色所示部分就是合格的剪取。 
 
請你計算,一共有多少種不一樣的剪取方法。 

輸出

請填寫表示方案數目的整數。 
 
分析1
          使用開鎖解鎖機制、經過DFS一邊搜索一邊計數,每積累5個方格就中止進一步搜索,同時將結果存儲起來。
   可是三、五、六、七、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 }

 分析2ios

    爲了彌補分析1所提出的漏洞,須要用BFS與DFS相結合,才能獲得全部狀況,如下是BFS與DFS結合解題的代碼。spa

  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 }
相關文章
相關標籤/搜索