首页 > 其他 > 详细

uva 140 带宽

时间:2020-10-05 15:20:55      阅读:20      评论:0      收藏:0      [点我收藏+]

对于本题,因为数据范围在8!内,我们只需枚举这些字母的全排列就能解决问题,用u和v一起存图,u里为所有边起点,v为终点,枚举全排列,随时更新最值即可。

#include<bits/stdc++.h>
using namespace std;
int id[256],letter[10]; 
int main() {
    int n;
    char a[10000];
    while(scanf("%s",a)==1&&a[0]!=#)
    {
        n=0;
    for (char ch = A; ch <= Z; ch++)
            if (strchr(a, ch) != NULL) {//寻找字符第一次出现的位置。 
                id[ch] = n++;//记录该字符的编号 
                letter[id[ch]] = ch;//记录编号几出现的是啥字符 
            }
        int len = strlen(a), p = 0, q = 0;
        vector<int> u, v;
        for (;;) {
            while (p < len && a[p] != :) p++;
            if (p == len) break;
            while (q < len && a[q] != ;) q++;
            for (int i = p + 1; i < q; i++) {
                u.push_back(id[a[p - 1]]);//存储当前位置的起始边 
                v.push_back(id[a[i]]);
            }
            p++; q++;
        }int P[maxn], bestP[maxn], pos[maxn], ans = n;
        for (int i = 0; i < n; i++) P[i] = i;
        do {
            for (int i = 0; i < n; i++) pos[P[i]] = i; // 每个字母的位置
            int bandwidth = 0;
            for (int i = 0; i < u.size(); i++)
                bandwidth = max(bandwidth, abs(pos[u[i]] - pos[v[i]])); // 计算带宽
            if (bandwidth < ans) {
                ans = bandwidth;
            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\n", ans);
    }
    }
    return 0;
}

如果想提高效率,本题也可以用回溯法完成,用邻接矩阵存图,在全排列额过程中剪枝减少计算量。完成全排列的枚举。时间效率会稍有提高

#include<bits/stdc++.h>
using namespace std;
const int N=10;
int n,id[Z+1],G[N][N];//为每个字母节点编个号。
int ans,seq[N],tmp[N];
bool used[N];
char u,v,letter[N];//letter[i]记录节点 i 的字母值
inline int dis(int cur,int nid){
    for(int i=1;i<cur;i++)
        if(G[tmp[i]][nid])
            return cur-i;
    return 0;
}
void dfs(int cur,int bw){
    if(cur>n){
        ans=bw;
        memcpy(seq,tmp,sizeof(seq));
        return;
    }
    //1-n 的全排列
    for(int i=1;i<=n;i++)
        if(!used[i]){
            bw=max(bw,dis(cur,i));//计算当前的 bandwidth 值
            if(bw<ans){
                used[i]=true;
                tmp[cur]=i;
                dfs(cur+1,bw);
                used[i]=false;
            }
        }
}
int main(){
    string line,node;
    char u,v;
    while(cin>>line&&line!="#"){
        n=0,ans=10;
        memset(G,0,sizeof(G));
        memset(id,0,sizeof(id));
        memset(used,0,sizeof(used));
        for(char i=A;i<=Z;i++)
            if(line.find(i)!=-1){
                id[i]=++n;
                letter[n]=i;    }
        for(int i=0;i<line.size();i++)
            if(line[i]==;) line[i]= ;
        stringstream sin(line);
        while(sin>>node){
            node[node.find(:)]= ;
            stringstream ss(node);
            ss>>u;
            while(ss>>v)
                G[id[u]][id[v]]=G[id[v]][id[u]]=1;
        }
        dfs(1,0);
        for(int i=1;i<=n;i++)
            cout<<letter[seq[i]]<< ;
        cout<<"-> "<<ans<<endl; 
    }
    return 0;
}

 

uva 140 带宽

原文:https://www.cnblogs.com/tscjj/p/13769936.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!