否定的なリング----------- word ring

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;
}
公開された164元の記事 ウォンの賞賛112 ビュー6767

おすすめ

転載: blog.csdn.net/qq_45772483/article/details/105479112