第5节 宝岛探险
利用广度优先搜索实现
其中可以不用开辟visit变量,直接用将本身的值改为-1,然后判断即可
注意输入数据时周围加了一层-1,作为边界
广度优先搜索
利用深度优先搜索实现,注意下面的方法是将搜索到的点着成-1的颜色
深度优先搜索
注意如果n和m比较大的话,建议用广度优先搜索,
由于深度优先搜索,一直按照深度优先下去,故最坏情况为n*m,
而广度优先搜索,的最坏情况是max(n,m)
关于求小岛的数量,只需要对每个点遍历一边,如果该点是陆地的话,进行深度优先搜索
#include <iostream> #include <vector> #include <algorithm> #include <queue> #include <utility> using namespace std; int dx[] = {-1,0,1,0}; int dy[] = {0,1,0,-1}; typedef pair<int,int> Point; typedef vector<vector<int> > VectorArray; void dfs(int x, int y, VectorArray& a){ for(int i = 0 ; i < 4; ++ i){ int newx = x+dx[i], newy = y + dy[i]; if(a[newx][newy] > 0){ a[newx][newy] = -1; dfs(newx,newy,a); } } } int main(){ int n,m,x,y; cin >> n >> m; vector<vector<int> > a(n+2,vector<int>(m+2,-1)); for(int i = 1 ; i <= n; ++ i){ for(int j = 1 ; j <= m; ++ j){ cin >> a[i][j]; } } int ans = 0 ; for(int i = 1; i <= n; ++ i){ for(int j =1; j <= m ; ++ j){ if(a[x][y] > 0){ ans++; a[x][y]=-1; dfs(x,y,a); } } } cout<<ans<<endl; }
第6节 水管工游戏
此题题目感觉非常好,有兴趣的话可以先试玩一下水管工游戏
直管有两种,进水口有4种可能,上下左右,每种进水口对应的出水口只有一种可能
弯管有4种,进水口有4种可能,上下左右, 每种进水口对应的出水口有两种可能,因为弯管可以旋转
然后深度搜索每种可能
#include <iostream> #include <vector> #include <stack> #include <algorithm> #include <utility> using namespace std; typedef pair<int,int> Point; typedef vector<vector<int> > VVI; typedef vector<vector<bool> >VVB; stack<Point> res; int n,m; vector<vector<Point> > solutions; bool flag = false; void dfs(int x, int y, int direction,VVI& a, VVB& visit){ if(flag) return; if(x == n && y== m+1){ flag = true; while(!res.empty()){ Point p = res.top();res.pop(); cout<<"("<<p.first<<","<<p.second<<")->"; } cout<<endl; return; } if(visit[x][y]) return; visit[x][y] = true; res.push(Point(x,y)); if(a[x][y] == 5 || a[x][y] == 6){ switch(direction){ case 1:dfs(x,y+1,1,a,visit); case 2:dfs(x+1,y,2,a,visit); case 3:dfs(x,y-1,3,a,visit); case 4:dfs(x-1,y,4,a,visit); } } if(a[x][y]>=1 && a[x][y] <= 4){ switch(direction){ case 1:{dfs(x+1,y,2,a,visit);dfs(x-1,y,4,a,visit);} case 2:{dfs(x,y+1,1,a,visit);dfs(x,y-1,3,a,visit);} case 3:{dfs(x-1,y,4,a,visit);dfs(x+1,y,2,a,visit);} case 4:{dfs(x,y+1,1,a,visit);dfs(x,y-1,3,a,visit);} } } visit[x][y] = false; res.pop(); return; } int main(){ cin >> n >> m; vector<vector<int> > a(n+2,vector<int>(m+2,-1)); vector<vector<bool> > visit(n+2,vector<bool>(m+2,true)); for(int i = 1; i <= n ; ++ i){ for(int j = 1; j <= m ; ++ j){ cin >> a[i][j]; visit[i][j] = false; } } dfs(1,1,1,a,visit); if(!flag) cout<<"impossible"<<endl; }