洛谷 1019 单词接龙

【题解】
入门搜索题。
先n方枚举每对单词,计算他们接龙可以让长度延长多少,可以延长的在链式前向星中加边。
搜索的时候按照边表逐个扩展就好了。
【代码】
#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long
#define rg register
#define N 1010
using namespace std;
int n,ans,tot,last[N],len[N],v[N];
char a[N][N],st;
struct edge{
int to,pre,del;
}e[200010];
inline int read(){
int k=0,f=1; char c=getchar();
while(c<'0'||c>'9')c=='-'&&(f=-1),c=getchar();
while('0'<=c&&c<='9')k=k*10+c-'0',c=getchar();
return k*f;
}
inline void calc(int x,int y){
int st=max(2,len[x]-len[y]+2),del=0;
// printf("%d %d %d\n",x,y,st);
for(rg int i=st;i<=len[x];i++){
bool ok=1;
for(rg int j=1;j<=len[x]-i+1;j++)if(a[x][i+j-1]!=a[y][j]){
ok=0; break;
}
if(ok) del=len[y]-(len[x]-i+1);
}
if(del>0){
e[++tot]=(edge){y,last[x],del}; last[x]=tot;
// printf("[%d %d del=%d]\n",x,y,del);
}
}
void dfs(int now,int lenth){
ans=max(ans,lenth);
for(rg int i=last[now],to;i;i=e[i].pre)if(v[to=e[i].to]<2){
v[to]++;
dfs(to,lenth+e[i].del);
v[to]--;
}
}
int main(){
n=read();
for(rg int i=1;i<=n;i++){scanf("%s",a[i]+1); len[i]=strlen(a[i]+1);}
st=getchar(); while((!('a'<=st&&st<='z'))&&(!('A'<=st&&st<='Z'))) st=getchar();
// for(rg int i=1;i<=n;i++) printf("[%s]\n",a[i]+1);
for(rg int i=1;i<=n;i++)
for(rg int j=1;j<=n;j++) calc(i,j);
for(rg int i=1;i<=n;i++)if(a[i][1]==st){
v[i]++; dfs(i,len[i]); v[i]--;
}
printf("%d\n",ans);
return 0;
}

浙公网安备 33010602011771号