nn個の文字列があり、各文字列は〜za〜zの小文字の英語の文字で構成されています。
文字列AAの最後の2文字が文字列BBの最初の2文字と完全に一致する場合、AAとBBを接続できると言います(注:AAをBBに接続できるということは、BBをAAに接続できるという意味ではありません)。
与えられた文字列からいくつかを見つけて、それらを端から端まで接続してリング文字列を形成し(文字列も端から端まで接続されています)、このリング文字列の平均長を最大化したいと考えています。
次の例:
ababc
bckjaca
caahoynaab
最初の文字列は2番目の文字列に接続でき、2番目の文字列は3番目の文字列に接続でき、3番目の文字列は最初の文字列に接続でき、この順序で接続してリング文字列、長さを形成します5 + 7 + 10 = 225 + 7 + 10 = 22(繰り返し部分は2回カウントされます)で、合計33個の文字列が使用されるため、平均の長さは223≈7.33223≈7.33です。
入力形式
この質問には複数のデータセットがあります。
各データグループの最初の行である整数nnは文字列の数を表し、
次のnn行は各行が10001000以下の文字列です。
読み込みはn = 0n = 0で終わります。
出力形式
リングストリングがない場合は「解なし」を出力します。それ以外の場合は、最長のリングストリングの平均長が出力されます。
回答と標準回答の差が0.010.01を超えない限り、回答は正しいと見なされます。
データ範囲
1≤n≤1051≤n≤105
入力サンプル:
3
intercommunicational
アルキルベンゼンスルホン
tetraiodophenolphthalein
0
出力例:
21.66
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 700, M = 100010;
int n;
int h[N], e[M], w[M], ne[M], idx;
double dist[N];
int q[N], cnt[N];
bool st[N];
void add(int a, int b, int c){
e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx ++;
}
bool check(double mid){
memset(st, 0, sizeof st);
memset(cnt, 0, sizeof cnt);
int hh = 0, tt = 0;
for (int i = 0; i < 676; i ++){
q[tt ++] = i;
st[i] = true;
}
int count = 0;
while(hh != tt){
int t = q[hh ++];
if (hh == N) hh = 0;
st[t] = false;
for (int i = h[t]; ~i; i = ne[i]){
int j = e[i];
if (dist[j] < dist[t] + w[i] - mid){
dist[j] = dist[t] + w[i] - mid;
cnt[j] = cnt[t] + 1;
if (++ count > 10000) return true;
if (cnt[j] >= N) return true;
if (!st[j]){
q[tt ++] = j;
if (tt == N) tt = 0;
st[j] = true;
}
}
}
}
return false;
}
int main(){
char str[1010];
while(scanf("%d", &n), n){
memset(h, -1, sizeof h);
idx = 0;
for (int i = 0; i < n; i ++){
scanf("%s", str);
int len = strlen(str);
if (len >= 2){
int left = (str[0] - 'a') * 26 + str[1] - 'a';
int right = (str[len - 2] - 'a') * 26 + str[len - 1] - 'a';
add(left, right, len);
}
}
if (!check(0)) puts("No solution");
else{
double l = 0, r = 1000;
while(r - l > 1e-4){
double mid = (l + r) / 2;
if (check(mid)) l = mid;
else r = mid;
}
printf("%lf\n",l);
}
}
return 0;
}