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 }
可以的话,记得帮我点个推荐,然后收藏+关注哟