zoukankan      html  css  js  c++  java
  • 假回溯-uva140带宽

    题目链接:https://vjudge.net/problem/UVA-140

    题解:这道题利用全排函数即可解决,但是这道题技巧性强,稍微不注意就会超时,一开始没有想起全排函数,自己写回溯全排超时了,主要问题出在:1、递归过程中疯狂判断最小带宽,循环太多了。2、处理原字符串的方法太LOW了。在借鉴了紫书思路的之后写出了AC代码如下:

    AC代码:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<vector>
    #define MAXN 30
    using namespace std;
    typedef long long ll;
    
    vector<int> u;
    vector<int> v;
    
    int main(void){
        char s[1000];
        while(scanf("%s",s) == 1 && s[0] != '#'){
            u.clear();
            v.clear();
            int len = strlen(s);
            int p = 0,q = 0;
            int n = 0;
            int id[256];
            char letter[MAXN];
            for(char i = 'A';i<='Z';i++){
                if(strchr(s,i) != NULL){
                    id[i] = n++;
                    letter[id[i]] = i;
                }
            }
            for(;;){
                if(p<len && q < len){
                    while(1){
                        if(s[p] == ':'){
                            break;
                        }
                        p++;
                        if(p == len){
                            break;
                        }
                    }
                    while(1){
                        if(s[q] == ';'){
                            break;
                        }
                        q++;
                        if(q == len){
                            break;
                        }
                    }
                    for(int i = p+1;i<q;i++){
                        u.push_back(id[s[p - 1]]);
                        v.push_back(id[s[i]]);
                    }
                }
                else
                    break;
                p++;q++;
            }
            int P[MAXN],BESTP[MAXN];
            int pos[MAXN];
            int best = n;
            for(int i = 0;i<n;i++){
                P[i] = i;
            }
            do{
                for(int i = 0;i<n;i++){
                    pos[P[i]] = i;
                }
                int bandwith = 0;
                for(int i = 0;i<u.size();i++){
                    bandwith = max(bandwith,abs(pos[u[i]]-pos[v[i]]));
                }
                if(bandwith < best){
                    best = bandwith;
                    memcpy(BESTP,P,sizeof(P));
                }
            }while(next_permutation(P,P+n));
            for(int i = 0; i < n; i++) printf("%c ", letter[BESTP[i]]);
            printf("-> %d
    ", best);
        }
        return 0;
    }

    超时代码:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<iostream>
    #include<string>
    #include<cmath>
    #define MAXN 30
    using namespace std;
    typedef long long ll;
    int mmin;
    int maxalp;
    int nowMin;
    int graph[MAXN][MAXN];
    int nowbox[MAXN];
    int ansbox[MAXN];
    void findNiceList(int cur){
        if(cur - 1 == maxalp){
            int ok = 1;
            int nowbig;
            int big1;
            int big = 0;
            for(int i =0;i<cur;i++){
                big1 = 0;
                if(!ok){
                    break;
                }
                int nowchar =  nowbox[i];
                for(int j = 0;j<=maxalp;j++){
                    if(graph[nowchar][j] == 1){
                        nowbig = abs((find(nowbox,nowbox+cur,j) - nowbox) - i);
                        if(nowbig > big1){
                            big1 = nowbig;
                        }
                        if(big1 >= mmin){
                            ok = 0;
                            break;
                        }
                    }
                }
                if(big1 > big){
                    big = big1;
                }
            }
            nowMin = big;
            if(nowMin < mmin && ok){
                for(int i = 0;i<=maxalp;i++){
                    ansbox[i] = nowbox[i];
                    mmin = nowMin;
                }
            }
        }
        else{
            for(int i = 0;i<=maxalp;i++){
                int ok = 1;
                for(int j = 0;j<cur;j++){
                    if(nowbox[j] == i){
                        ok = 0;
                        break;
                    }
                }
                if(ok){
                    nowbox[cur] =  i;
                    findNiceList(cur+1);
                }
            }
        }
    }
    
    /*void graphprint(void){
        for(int i = 0;i<=maxalp;i++){
            printf("%c:",'A'+i);
            for(int j = 0; j<MAXN;j++){
                if(graph[i][j] == 1){
                    printf("%c ",j+'A');
                }
            }
            printf("
    ");
        }
    }*/
    
    int main(void){
        string inistr;
        const string endstr = "#";
        while((cin >> inistr) && inistr != endstr){
            memset(graph,-1,sizeof(graph));
            int len = inistr.size();
            maxalp = -1;
            mmin = 99;
            nowMin = 0;
            for(int i = 0;i < len;i++){
                if(inistr[i] <= 'Z' && inistr[i] >='A'){
                    if(inistr[i] - 'A' > maxalp){
                        maxalp = inistr[i] - 'A';
                    }
                }
                if(i+1 == len || inistr[i+1] == ';'){
                    int okindex;
                    for(int m = i - 1;m>=0;m--){
                        if(inistr[m] == ':'){
                            okindex = m;
                            break;
                        }
                    }
                    for(int m = okindex + 1;m<=i;m++){
                        graph[inistr[okindex - 1] - 'A'][inistr[m] - 'A'] = 1;
                        graph[inistr[m] - 'A'][inistr[okindex - 1] - 'A'] = 1;
                    }
                }
            }
            findNiceList(0);
            for(int i = 0;i<=maxalp;i++){
                printf("%c ",ansbox[i] + 'A');
            }
            printf("-> ");
            printf("%d
    ",mmin);
        }
        return 0;
    }
  • 相关阅读:
    linux下给U盘分区&制作文件系统
    迭代器 配接器
    仿函数
    在查询用户的权限的时候 使用左外连接 和 access数据库中左外连接
    C# 想要程序文件移动 而数据保持相对位置
    C# 第三方控件 下面的Item不显示了
    C# 第三方控件 错误 LC-1
    c# 第三方控件 闪退
    access 语句错误
    poj 1469(二分图 最大匹配)
  • 原文地址:https://www.cnblogs.com/doubest/p/10175683.html
Copyright © 2011-2022 走看看