• 穷搜


    深度搜索

    POJ 1979

    • POJ 1979题目链接
      这个题目跟找池子差不多 ,而且这个题只要找片同色的瓦块的区域, 很明显的可以用深度搜索。
    #include<iostream>
    #include<string.h>
    
    using namespace std;
    
    char mat[1002][1002];
    int m, n;
    int dx[] = {0, 0, -1, 1};
    int dy[] = {-1, 1, 0, 0};
    int ans;
    
    void dfs(int x, int y){
        mat[x][y] = '#';
    
        for(int i = 0; i < 4; ++i){
            int gx = x + dx[i], gy = y + dy[i];
            if(0 <= gx && gx < m && 0 <= gy && gy < n
               && mat[gx][gy] == '.'){
                   ans++;
                   dfs(gx, gy);
               }
        }
        return ;
    }
    
    int main(){
        while(cin>>n>>m && m > 0 && n > 0){
            memset(mat, 0, sizeof(mat));
            for(int i = 0; i < m; ++i){
                for(int j = 0; j < n; ++j){
                    cin>>mat[i][j];
                }
            }
            ans = 1;
            for(int i = 0; i < m; ++i){
                for(int j = 0; j < n; ++j){
                    if(mat[i][j] == '@'){
                        dfs(i, j);
                    }
                }
            }
            cout<<ans<<endl;
        }
        return 0;
    }
    
    

    AOJ0118

    • AOJ 0118题目链接
      这个题目就是把邻近相同的符号化为一块区域, 统计区域数目。
    #include<iostream>
    #include<string.h>
    
    using namespace std;
    
    char mat[1002][1002];
    int m, n;
    int dx[] = {0, 0, -1, 1};
    int dy[] = {-1, 1, 0, 0};
    int ans;
    
    
    int dfs(int x, int y, char ch){
        mat[x][y] = '.';
    
        for(int i = 0; i < 4; ++i){
            int gx = x + dx[i], gy = y + dy[i];
            if(0 <= gx && gx < m && 0 <= gy && gy < n
               && mat[gx][gy] == ch){
                   dfs(gx, gy, ch);
               }
        }
        return 0;
    }
    
    void solve(){
        memset(mat, 0, sizeof(mat));
        for(int i = 0; i < m; ++i){
            for(int j = 0; j < n; ++j){
                cin>>mat[i][j];
            }
        }
    
        ans = 0;
        for(int i = 0; i < m; ++i){
            for(int j = 0; j < n; ++j){
                if(mat[i][j] != '.'){
                    ans++;
                    dfs(i, j, mat[i][j]);
                }
            }
        }
        cout<<ans<<endl;
    }
    
    int main(){
        while(cin>>m>>n && m > 0 && n > 0){
            solve();
        }
        return 0;
    }
    
    

    AOJ 0033

    題意球掉在两个袋子里, 下来的球不能放在比他大的球上, 要求判断10个球能不能按要求下落。
    基本思路就是左右比较, 为了突出深度搜索,写成了递归额形式。

    #include<iostream>
    #include<string.h>
    
    using namespace std;
    
    int a[12];
    int n;
    
    bool dfs(int i, int left, int right){
        if(i == 10){
            return true;
        }
    
        if(a[i] > left && dfs(i + 1, a[i], right)){
            return true;
        }
        if(a[i] > right && dfs(i + 1, left, a[i])){
            return true;
        }
        return false;
    }
    
    void solve(){
        for(int i = 0; i < 10; ++i){
            cin>>a[i];
        }
    
        if(dfs(0, 0, 0)){
            cout<<"YES"<<endl;
        }
        else{
            cout<<"NO"<<endl;
        }
    }
    
    int main(){
        cin>>n;
        while(n--){
            solve();
        }
        return 0;
    }
    
    

    AOJ 3009

    • AOJ 3009 题目链接
      扔石头,上下左右四个方向如果某一个方向紧挨着block就不能扔这个方向,否则碰到block停住,block消失,再次四个方向扔。DFS老一套,不过一定要注意判断紧挨着的情况。超过最小步数剪枝也是个很有意思的技巧。
    #include<iostream>
    #include<string.h>
    
    const int VACANT_TYPE = 0;
    const int BLOCK_TYPE = 1;
    const int START_TYPE = 2;
    const int GOAL_TYPE = 3;
    const int MAX_THROW = 10;
    
    using namespace std;
    
    int mat[102][102];
    int m, n;
    int dx[] = {0, 0, -1, 1};
    int dy[] = {-1, 1, 0, 0};
    int ans;
    
    void dfs(int x, int y, int step){
        if(step >= MAX_THROW){
            return ;
        }
        for(int i = 0; i < 4; ++i){
            int gx = x, gy = y;
            while(true){
                gx += dx[i], gy += dy[i];
    
                if(gx < 0 || gx >= m || gy < 0 || gy >= n){
                    break;
                }
    
                if(mat[gx][gy] == GOAL_TYPE){
                    ans = min(ans, step + 1);
                    break;
                }
    
                if(mat[gx][gy] == BLOCK_TYPE){
                    mat[gx][gy] = VACANT_TYPE;
                    int prex = gx - dx[i], prey = gy - dy[i];
                    if(!(prex == x && prey == y)){
                        //剪枝
                        dfs(prex, prey, step + 1);
                    }
                    mat[gx][gy] = BLOCK_TYPE;
                    break;
                }
            }
        }
        return ;
    }
    
    void solve(){
        ans = 10000;
        memset(mat, -1, sizeof(mat));
        for(int i = 0; i < m; ++i){
            for(int j = 0; j < n; ++j){
                cin>>mat[i][j];
            }
        }
        for(int i = 0; i < m; ++i){
            for(int j = 0; j < n; ++j){
                if(mat[i][j] == START_TYPE){
                    dfs(i, j, 0);
                }
            }
        }
        if(ans == 10000){
            ans = -1;
        }
        cout<<ans<<endl;
    }
    
    
    int main(){
        while(cin>>n>>m && n >0 && m > 0){
            solve();
        }
        return 0;
    }
    
    
    

    广度搜索

    AOJ 0558

    输入m, n, N, 求 S->1, 1->2, 2->3, ..., 3->N的最短路径。

    #include<iostream>
    #include<string.h>
    #include<queue>
    
    using namespace std;
    
    typedef pair<int, int>P;
    int dx[] = {0, 0, -1, 1};
    int dy[] = {-1, 1, 0, 0};
    int m, n, N;
    char mat[1002][1002];
    int d[1002][1002];
    int ans;
    
    int bfs(int sx, int sy, int goal){
        memset(d, -1, sizeof(d));
        queue<P>que;
        que.push(P(sx, sy));
        d[sx][sy] = 0;
    
        while(que.size()){
            P p = que.front();
            que.pop();
            int x = p.first, y = p.second;
            if(mat[x][y] == goal){
                return d[x][y];
            }
    
            for(int i = 0; i < 4; ++i){
                int gx = x + dx[i], gy = y + dy[i];
                if(0 <= gx && gx < m && 0 <= gy && gy < n
                   && mat[gx][gy] != 'X' && d[gx][gy] == -1){
                       que.push(P(gx, gy));
                       d[gx][gy] = d[x][y] + 1;
                }
            }
        }
    }
    
    void solve(){
        for(int i = 0; i < m; ++i){
            for(int j = 0; j < n; ++j){
                cin>>mat[i][j];
            }
        }
    
        ans = 0;
        char start = 'S';
        for(int k = 0; k < N; ++k){
            char goal = '1' + k;
            for(int i = 0; i < m; ++i){
                for(int j = 0; j < n; ++j){
                    if(mat[i][j] == start){
                        ans += bfs(i, j, goal);
                    }
                }
            }
            start = goal;
        }
        cout<<ans<<endl;
    }
    
    int main(){
        while(cin>>m>>n>>N && m > 0 && n > 0){
            solve();
        }
        return 0;
    }
    
    

    AOJ 0121

    
    

    穷竭搜索

  • 相关阅读:
    DTOJ #3702. 月读(tsukuyomi)
    DTOJ #2311. 兔子与樱花 ( sakura )
    DTOJ #2416. 点燃的火焰(flame)
    dtoi4537 「TJOI / HEOI2016」树
    中科燕园gis外包------北京市人口普查地理信息系统
    中科燕园gis外包【动态标绘演示系统】v2.0 Flex版
    中科燕园GIS外包-----基于ArcGIS的应急平台
    arcgis server
    《深入理解ES6》之箭头函数
    【转】浏览器的工作原理:新式网络浏览器幕后揭秘
  • 原文地址:https://www.cnblogs.com/hichens/p/13332959.html
Copyright © 2020-2023  润新知