第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; }