1504:【例 1】Word Rings


【题目描述】

原题来自:Centrual Europe 2005

我们有 n 个字符串,每个字符串都是由 a 至 z 的小写英文字母组成的。如果字符串 A 的结尾两个字符刚好与字符串 B 的开头两个字符匹配,那么我们称 A 与 B 能够相连(注意:A 能与 B 相连不代表 B 能与 A 相连)。我们希望从给定的字符串中找出一些,使得它们首尾相连形成一个环串(一个串首尾相连也算),我们想要使这个环串的平均长度最大。如下例:

ababc
bckjaca
caahoynaab

 

第一个串能与第二个串相连,第二个串能与第三个串相连,第三个串能与第一个串相连,我们按照此顺序相连,便形成了一个环串,长度为 5+7+10=22(重复部分算两次),总共使用了 3 个串,所以平均长度是 <span id=”MathJax-Span-2″ class=”mrow”><span id=”MathJax-Span-3″ class=”mfrac”><span id=”MathJax-Span-4″ class=”mn”>22<span id=”MathJax-Span-5″ class=”mn”>3<span id=”MathJax-Span-6″ class=”mo”>≈<span id=”MathJax-Span-7″ class=”mn”>7.33223≈7.33。

【输入】

本题有多组数据。

每组数据的第一行,一个整数 n,表示字符串数量;

接下来 n 行,每行一个长度小于等于 1000 的字符串。

读入以 0 结束。

【输出】

若不存在环串,输出 No solution,否则输出最长的环串的平均长度。

只要答案与标准答案的差不超过 0.01,就视为答案正确。

【输入样例】

3
intercommunicational
alkylbenzenesulfonate
tetraiodophenolphthalein
0

【输出样例】

21.66

【提示】

数据范围:

对于全部数据,1≤n≤105​​ 。

【代码】

#include<iostream>

#include<cstring>

#include<cmath>

#include<algorithm>

#include<stack>

#include<cstdio>

#include<queue>

#include<map>

#include<vector>

#include<set>

using namespace std;

const int maxn=1e5+10;

const int INF=0x3fffffff;

const double eps=1e-4;

typedef long long LL;

char aa[1010];

int head[maxn],vis[maxn];

double dis[maxn];

int n,cnt;

struct node

{

int to,next,dis;

}

ed[maxn*10];

void add(int a,int b,int c)

{

ed[++cnt].to=b;

ed[cnt].dis=c;

ed[cnt].next=head[a];

head[a]=cnt;

}

int js(char a,char b)

{

return (a-‘a’)*26+(b-‘a’)+1;

}

bool spfa(int x,double mid)

{

vis[x]=1;

for(int i=head[x];i;i=ed[i].next)

{

int t=ed[i].to;

if(dis[x]+ed[i].dis-mid>dis[t])

{

dis[t]=dis[x]+ed[i].dis-mid;

 if(vis[t]||spfa(t,mid))

{

vis[x]=0;

return 1;

}

}

}

vis[x]=0;

return 0;

}

bool judge(double mid){

memset(dis,0,sizeof(dis));

for(int i=1;i<=26*26;i++)

{

if(spfa(i,mid))

return 1;

}

return 0;

}

int main()

{

while(scanf(“%d”,&n)&&n)

{

memset(vis,0,sizeof(vis));

memset(head,0,sizeof(head));

for(int i=0;i<n;i++)
{

scanf(“%s”,aa);

int len=strlen(aa);

add(js(aa[0],aa[1]),js(aa[len-2],aa[len-1]),len);

}

double mid,left=0,right=1000;

while(right-left>=eps)

{

mid=(left+right)/2;

if(judge(mid)) 

{

left=mid;

}

else right=mid;

}

if(left==0)

printf(“No solution/n”);

 else printf(“%.2lf/n”,left);

}

return 0;

}

 

原创文章,作者:3628473679,如若转载,请注明出处:https://blog.ytso.com/275124.html

(0)
上一篇 2022年7月18日
下一篇 2022年7月18日

相关推荐

发表回复

登录后才能评论