重构了好几遍最后WA#2......
望各位大佬帮忙
简述题意:找出一条词链使得,前一个词末字母等于后一个词首字母,中间用 . ,隔开,每个单词恰好出现一次,若无则输出 *** 。
错误信息:应该输出链,实则 euler() 函数搜不到,输出, *** 。
代码解释:
将词按字典序排序
以两端点为节点,词为边,从大到小加入链式前向星
check() 函数判断是否存在欧拉路径
euler() 进行顺序搜索
91分代码:
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<math.h>
#include<string.h>
#include<stack>
using namespace std;
typedef long long ll;
const int N=1e3+86;
int n;
string s[N];
//char s[N][28];
//struct side
//{
// int u;
// int v;
// int w;
// bool operator <(const side &x)const{
// if(u!=x.u) return u<x.u;
// if(v==x.v)
// {
// int len1=strlen(s[w]+1),len2=strlen(s[x.w]+1),len=min(len1,len2);
// for(int i=1;i<=len;i++)
// if(s[w][i]!=s[x.w][i]) return s[w][i]>s[x.w][i];
// return len1>len2;
// }
// return v>x.v;
// }
//}sd[N];
struct edge
{
int to;
int nxt;
int w;
}e[N];
int head[N],tot;
void add(int u,int v,int w){e[++tot].nxt=head[u],head[u]=tot,e[tot].to=v,e[tot].w=w;}
int INT(char c){return c-'a'+1;}
int in[28],out[28],sp,ans[N],vis[N],cnt;
bool check()
{
sp=1;
int cnts=0,cntt=0;
bool f=false;
for(int i=1;i<=26;i++)
{
if(in[i]!=out[i]) f=true;
if(out[i]-in[i]==1) sp=i,cnts++;
if(in[i]-out[i]==1) cntt++;
}
return (!f||(cnts==cntt&&cnts==1));
}
void euler(int u)
{
if(cnt==n)
{
for(int i=1;i<=n;i++)
{
cout<<s[ans[i]];
if(i<n) cout<<'.';
}
cout<<endl;
exit(0);
}
for(int i=head[u];i;i=e[i].nxt)
{
int v=e[i].to,w=e[i].w;
if(vis[w]) continue;
ans[++cnt]=w;
vis[w]=true;
euler(v);
vis[w]=false;
cnt--;
}
}
template<typename T>
inline void read(T &x)
{
T k=1;char ch=getchar();x=0;
while(ch<'0'||ch>'9'){if(ch=='-') k=-1;ch=getchar();}
while(ch>='0'&&ch<='9')x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
x*=k;
}
int main()
{
read(n);
// for(int i=1;i<=n;i++)
// {
// scanf("%s",s[i]+1);
// int len=strlen(s[i]+1);
// sd[i].u=INT(s[i][1]);
// sd[i].v=INT(s[i][len]);
// sd[i].w=i;
// out[INT(s[i][1])]++;
// in[INT(s[i][len])]++;
// }
// sort(sd+1,sd+1+n);
// for(int i=1;i<=n;i++)
// add(sd[i].u,sd[i].v,sd[i].w);
for(int i=1;i<=n;i++)
cin>>s[i];
sort(s+1,s+n+1);
for(int i=n;i>=1;i--)
add(INT(s[i][0]),INT(s[i][s[i].length()-1]),i),in[INT(s[i][s[i].length()-1])]++,out[INT(s[i][0])]++;
if(!check())
{
cout<<"***"<<endl;
return 0;
}
euler(sp);
cout<<"***"<<endl;
// if(cnt<n)
// {
// printf("***\n");
// return 0;
// }
// for(int i=1;i<=cnt;i++)
// {
// printf("%s",s[ans[i]]+1);
// if(i<cnt) putchar('.');
// }
// printf("\n");
return 0;
}
注释都是重构的血与泪......