《啊哈!算法》第4章 万能的搜索

 

第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;
    
}
水管工游戏

 

posted @ 2014-06-22 15:44  OpenSoucre  阅读(435)  评论(0编辑  收藏  举报