uva140

来源:互联网 发布:德温特专利数据库链接 编辑:程序博客网 时间:2024/04/30 09:20

全排列回溯剪枝。
题目数据很水。记录当前最小带宽,边回溯边计算当前序列最大的距离(也就是带宽),如果当前带宽超过了当前的最小带宽就剪枝。
注意下,数据读入时的字符串处理。

AC代码

#include<cstdio>#include<cstring>int G[26][26];const char a[27]="ABCDEFGHIJKLMNOPQRSTUVWXYZ";int n; //记录字母种类数 int v[26],ans[10],res[10],temp[10];int hard=10;//最终结果 int turn(char c){    return strchr(a,c)-a;}void dfs(int cur,int k){    if(cur==n&&k<hard)    {        hard=k;        for(int i=0;i<n;++i)        {            ans[i]=temp[i];        }        return ;    }    for(int i=0;i<n;++i)    {           int ok=1;        for(int j=0;j<cur;j++)        {            if(temp[j]==res[i])            {                ok=0;                break;            }        }        if(ok)        {        for(int j=0;j<cur;++j)        {            if(G[temp[j]][res[i]])            {                if((cur-j)>k)                k=cur-j;            }        }        if(k<hard)        {            temp[cur]=res[i];            dfs(cur+1,k);        }        }    }}int main(){    char s[150];    while(scanf("%s",s)==1&&s[0]!='#')    {        n=0,hard=10;        memset(v,0,sizeof(v));        memset(G,0,sizeof(G));        for(int i=0,j=0;;++j)        {            if(s[j]==';'||s[j]=='\0')            {                int x=turn(s[i]),y=i+2;                v[x]++;                while(y!=j)                {                    int t=turn(s[y]);                    G[x][t]=1;                    G[t][x]=1;                    ++y;                    v[t]++;                }                i=j+1;            }            if(s[j]=='\0')            break;        }        for(int i=0;i<26;++i)        {            if(v[i]) res[n++]=i;        }    //  printf("%d\n",n); //打印字母个数         dfs(0,1);        for(int i=0;i<n;++i)        {        if(i==n-1)        printf("%c -> %d",'A'+ans[i],hard);        else printf("%c ",'A'+ans[i]);        }        printf("\n");    }    return 0;}

如有不当之处欢迎指出!

0 0
原创粉丝点击