第一次写回溯。。发生了很多错误(虽然回溯应该是很简单的算法了,就是剪剪枝而已)
可能也有思考不全的因素,一开始老是想多减点枝,结果减多了。。虽然第一次的时间确实很可观。~
有一点可能很uva上题目的描述不一样,uva上说a single upper case character in the the range `A‘ to `Z‘), followed by a `:‘
节点只有一个的意思,但是貌似不是这样。。回去要搜搜其他大神的代码,多优化一下了。
#include<bits/stdc++.h> using namespace std; const int maxn=100;char s[maxn]; int kase=0,a[50],most[50],small,vis[maxn],A[50]; vector<int> G[20]; map<int,int> p; void dfs(int cur) { if(cur==kase) { int h=-1; for(int i=0;i<kase;i++) for(int j=0;j<G[most[i]].size();j++){ int v=G[most[i]][j],k; for( k=0;k<kase;k++) if(most[k]==v) break; if(abs(i-k)>h) h=abs(i-k); } small=h; for(int j=0;j<kase;j++) A[j]=most[j];return ; } for(int i=0;i<kase;i++){ if(!vis[a[i]]){ int ok=1; most[cur]=a[i]; vis[a[i]]=1; for(int m=0;m<=cur;m++){ for(int j=0;j<G[most[m]].size();j++){ int v=G[most[m]][j],k; if(vis[v]){ for(k=0;k<cur;k++) if(most[k]==v) break; if(abs(m-k)>=small) { ok=0;break; } } } if(!ok) break; } if(ok) dfs(cur+1); vis[a[i]]=0; } } } int main() { while(scanf("%s",s)!=EOF) { if(s[0]=='#') return 0; kase=0; int n=strlen(s); int star=0,maohao; for(int i=0;i<n;i++){ if(isupper(s[i])&&!p.count(s[i]-'A')) { p[s[i]-'A']=1; a[kase++]=s[i]-'A'; } if(s[i]==';'||i==n-1) { if(i==n-1) i++; for(int j=star;j<i;j++) if(s[j]==':') { maohao=j; break; } for(int j=star;j<maohao;j++) for(int k=maohao+1;k<i;k++) { G[s[j]-'A'].push_back(s[k]-'A'); G[s[k]-'A'].push_back(s[j]-'A'); } star=i+1; } } sort(a,a+kase);small=100000; memset(vis,0,sizeof(vis)); dfs(0) ; for(int i=0;i<kase;i++) printf("%c ",A[i]+'A');printf("-> %d\n",small); for(int i=0;i<30;i++) G[i].clear(); p.clear(); } return 0; }
原文地址:http://blog.csdn.net/weizhuwyzc000/article/details/44224551