zoukankan      html  css  js  c++  java
  • UVA 11882 Biggest Number 深搜 剪枝

    如图,给一个图,每个格子只能走一次,起点终点任意,求按路径顺序将格子里的数字拼在一起,最大的数字。

    很容易想到用暴力求解的方法,但最多会有 30 个格子,O(2^30) 肯定超时了。

    考虑剪枝,设当前已经找到一个 ans,若当前路径的最大长度小于 ans 的长度,则不可能比 ans 大,剪掉, 若等于,则考虑当前路径已经形成的数字(假设 n 位),若小于 ans 的前 n 位,则剪掉。

    代码:

    #include <iostream>
    #include <cstring>
    #include <queue>
    #include <vector>
    #include <algorithm>
    using namespace std;
    
    const int MAX = 20;int dx[4] = {-1, 0, 1, 0};
    int dy[4] = { 0, 1, 0,-1};
    char G[MAX][MAX];
    int vis[MAX][MAX];
    int vis2[MAX][MAX];
    string ans;
    int r, c;
    
    void dfs(int i, int j, string sum);        //暴力求解 
    int getLen(int i, int j);                //求在 i,j点开始走,最长的路径是多少 
    string maxSum(string s1, string s2);    //比较两个数字 
    
    int main(){
        freopen("input.txt", "r", stdin);
        
        while(cin >> r >> c){
            if(r == 0 && c == 0)
                break;
            
            for(int i=1; i<=r; i++){
                for(int j=1; j<=c; j++){
                    cin >> G[i][j];
                }
            }
            
            ans = "";
            
            for(int i=1; i<=r; i++){
                for(int j=1; j<=c; j++){
                    if(G[i][j] != '#'){
                        memset(vis, 0, sizeof(vis));
                        dfs(i, j, "");
                    }
                }
            }
            
            cout << ans << endl;
        }
        
        return 0;
    } 
    
    void dfs(int i, int j, string sum){
        if(vis[i][j] == 1)
            return ;
        
        sum = sum + G[i][j];
        memcpy(vis2, vis, sizeof(vis)); 
        int len = getLen(i, j) - 1;
        
        if(len + sum.length() < ans.length()){        //长度不够 
            return ;
        }
        
        if(len + sum.length() == ans.length()){        //长度相同,但不可能比答案更大 
            if(sum < ans.substr(0, sum.length()))
                return ;
        }
        
        if(len == 0){        //更新一个答案 
            ans = maxSum(ans, sum);
            return ;
        }
        
        vis[i][j] = 1;
        
        for(int k=0; k<4; k++){
            int x = i + dx[k], y = j + dy[k];
            if(x < 1 || x > r || y < 1 || y > c || G[x][y] == '#' || vis[x][y] == 1){
                continue;
            }else{
                dfs(x, y, sum);
            }
        }
        
        vis[i][j] = 0;
        
    }
    
    int getLen(int i, int j){
        if(vis2[i][j] == 1)
            return 0;
        vis2[i][j] = 1;
        int sum = 1;
        for(int k=0; k<4; k++){
            int x = i + dx[k];
            int y = j + dy[k];
            if(x < 1 || x > r || y < 1 || y > c || vis2[x][y] || G[x][y] == '#')
                continue;
            sum += getLen(x, y);
        }
        return sum;
    }
    
    string maxSum(string s1, string s2){
        if(s1.length() == s2.length())
            return max(s1, s2);
        else{
            if(s1.length() > s2.length())
                return s1;
            return s2;
        }
    }
  • 相关阅读:
    异常处理
    组合,封装
    自我介绍
    27python更多实例
    28python类代码编写细节
    29python运算符重载
    30python 类的设计
    31python类的高级主题
    32python异常基础
    33python异常编码细节
  • 原文地址:https://www.cnblogs.com/lighter-blog/p/7269517.html
Copyright © 2011-2022 走看看