單詞接龍1

單詞接龍1
題目描述
Bsny從字典挑出N個單詞,並設計了接龍游戲,只要一個單詞的最後兩個字母和另一個單詞的前兩個字母相同,那麼這兩個單詞就可以有序的連接起來。

Bsny想要知道在所給的所有單詞中能否按照上述方式接龍組成一個單詞環(可能是多個),若能,求所有環的環中單詞平均長度最大值。

輸入
第一行一個整數N,表示單詞數量。

接下來N行,每行一個字符串,僅包含小寫字母。

輸出
若能組成單詞環,輸出環中單詞的最大平均長度,結果保留2位小數;否則輸出”No solution.”(不包括雙引號)。精度誤差在0.01都算正確。

樣例輸入
3
intercommunicational
alkylbenzenesulfonate
tetraiodophenolphthalein
樣例輸出
21.67
提示
20%的數據:n≤20;

70%的數據:n≤1000;

100%的數據:n≤100000,每個單詞長度不超過1000。輸入數據比較大,C/C++的同學用scanf輸入。


1.2.3.LCA

splay

DoubleIEEE648:

1.79769313486231570E+3084.94065645841246544E324

4.94065645841246544E3241.79769313486231570E+308

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
char ch[1050];
double dis[1000],val[500050],val1[500050];
int hed[1000],vet[500050],Next[500050],q[5000500],inq[1000];
bool inn[1000],flag[1000],ff[1000];
int num;
int nn;
void add(int u,int v,int len){
  ++num;
    vet[num]=v;
    val[num]=len;
    //cout<<num<<" "<<val[num]<<endl;
    val1[num]=len;
    //cout<<val[num]<<endl;
    Next[num]=hed[u];
    hed[u]=num;
}
bool spfa(int x){
  for (int i=0;i<=675;++i) dis[i]=-100000000000,inn[i]=false;
    int head=0,tail=0;
    q[head]=x;
    inn[x]=true;
    dis[x]=0;
    while (head<=tail){
        int u=q[head];
        ff[u]=false;
        ++head;
        inn[u]=false;
        for (int i=hed[u];i!=-1;i=Next[i]){
          int v=vet[i];
            if (dis[u]+val[i]>dis[v]){
              dis[v]=dis[u]+val[i];
                if (inn[v]==false){
                  inn[v]=true;
                    ++tail;
                    q[tail]=v;
                    ++inq[v];
                    if (inq[v]>=nn) return 1;
                }
            }
        }
    }
    return 0;
}
bool check(int x){
    for (int i=0;i<=675;++i) {ff[i]=true;inq[i]=0;}
    //cout<<"ha"<<endl;
  for (int i=0;i<=675;++i)
    if (flag[i]&&ff[i]){
        if (spfa(i)) return 1;
    }
    return 0;
}
int main(){
    int n;
    scanf("%d",&n);
    for (int i=0;i<=675;++i) {hed[i]=-1;flag[i]=false;}
    num=0;
    nn=0;
    for (int i=1;i<=n;++i){
      scanf("%s",ch);
        int len=strlen(ch);
        int u=(ch[0]-'a')*26+(ch[1]-'a');
        int v=(ch[len-2]-'a')*26+(ch[len-1]-'a');
        add(u,v,len);
        if (flag[u]==false) ++nn;
        if (flag[v]==false) ++nn;
        flag[u]=true;
        flag[v]=true;
    }
    double l=1;
    double r=1000;
    while (r-l>0.001){
      double mid=(l+r)/2;
        for (int i=1;i<=n;++i) val[i]=val1[i]-mid;
        //for (int i=1;i<=n;++i) cout<<val1[i]<<" "<<mid<<" "<<val[i]<<endl;
        //cout<<endl;
    if (check(1)) l=mid;else r=mid;
    }
    if (l>1) printf("%.2lf\n",l);
    else printf("No solution.\n");
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章