这道题直接给代码,暴力枚举很简单,注意对细节的理解,代码中会有详细解释:
题目链接:https://vjudge.net/problem/UVA-140
#include <bits/stdc++.h>
using namespace std;
const int maxn=1000+10;
char s[maxn];
//注意本题的重点在于各个字母之间的位置关系,而非字母的大小关系,很容易混淆!!!
int main()
{
while(scanf("%s",s)==1&&s[0]!='#')
{
//数据读取
int n=0,id[maxn],letter[maxn];
for(char ch='A';ch<='Z';ch++)
{
if(strchr(s,ch)!=NULL)
{
id[ch]=n++;
letter[id[ch]]=ch;//用lettet储存位置上代表字母的ASCLL值;
}
}
vector<int> u,v;
int p=0,q=0,len=strlen(s);
//数据分类处理
for(;;)
{
while(q<len&&s[q]!=':') q++;
if(q>=len) break;
while(p<len&&s[p]!=';') p++;
for(int i=q+1;i<p;i++)
{
u.push_back(id[s[q-1]]);//在U,V中储存存在关系的字母(注意里面存的是各个字母的位置)
v.push_back(id[s[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;//这里有链表的意思,通过变化的P[i]来保存各个字母变化后的位置
int brandwidth=0;
for(int i=0;i<u.size();i++)
brandwidth=max(brandwidth,abs(pos[u[i]]-pos[v[i]]));
if(brandwidth<ans)
{//每次找到更优解后,便进行复制
ans=brandwidth;
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;
}