zoukankan      html  css  js  c++  java
  • HihoCoder1644 : 完美命名的烦恼([Offer收割]编程练习赛37)(有向图的一笔画问题||欧拉路)

    描述

    程序员常常需要给变量命名、给函数命名、给项目命名、给团队命名…… 好的名字可以大大提高程序员的主观能动性,所以很多程序员在起名时都会陷入纠结和烦恼。

    小Hi希望给新的项目起个完美的名字。首先小Hi给出了新项目的N个长度相等(均为L)的关键字,他希望能找到一个完美名字:这个名字的长度恰好为N+L-1,并且其中N个长度为L的子串恰好是给定的N个关键字。  

    例如对于关键字cat、ate、tea有完美的名字:catea。  

    给定N个长度相等的关键字,请你帮小Hi找到一个完美的名字。

    输入

    第一行包含一个整数N。  

    以下N行每行包含一个长度为L的关键字。  

    对于30%的数据,1 ≤ N ≤ 10  

    对于100%的数据,1 ≤ N ≤ 50000,1 ≤ L ≤ 10,关键字只包含小写字母。

    输出

    如果存在完美的名字,你可以输出任意一个。如果不存在,输出NO。

    样例输入

    3  
    ate  
    cat  
    tea

    样例输出

    catea

     模型:成语接龙。

    以前做过类似的题,有所灵感,知道怎么建图。

    • 如单词abcd,我们加一条有向边abc->bcd,
    • 那么ate,cat,tea,就是有边at->te, ca->at, te->ea。那么一笔画就是ca->at->te-ea,得到catea。

    做完的感触。

    • 真的是wa了好久,主要是没有考虑只有一个字母长度的情况(毕竟代码里有‘L-2’这个东西)
    •  注意‘NO’的情况,如果不能连通;如果连通了但是不满足欧拉路的条件(无奇点,或一个起点一个终点)
    • 逆序输出。
    #include<cstdio>
    #include<cstdlib>
    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<map>
    using namespace std;
    const int maxn=200010;
    map<string,int>mp;
    map<int,string>name;
    char c[20];string s1,s2;
    int Laxt[maxn],Next[maxn],To[maxn],cnt,tot,num;//边,点,路 
    int id[maxn],od[maxn],used[maxn],path[maxn]; 
    int a[maxn],b[maxn];//起点;
    void add(int u,int v)
    {
        Next[++cnt]=Laxt[u];
        Laxt[u]=cnt;
        To[cnt]=v;
    }
    void dfs(int u)                  //Fluery算法 
    {
        for(int i=Laxt[u];i;i=Next[i]){
            if(!used[i]){
                used[i]=1;
                dfs(To[i]);
            }    
        }
        path[++num]=u;
    }
    int main()
    {
        int n,i,j,L;bool Flag=false;
        scanf("%d",&n);
        for(i=1;i<=n;i++){
            scanf("%s",c);
            L=strlen(c);
            if(L==1){
                cout<<c[0];
                Flag=true;
            }
            s1=s2="";
            for(j=0;j<L-1;j++)s1+=c[j];
            for(j=1;j<L;j++) s2+=c[j];
            if(mp.find(s1)==mp.end()) mp[s1]=++tot,name[tot]=s1;
            if(mp.find(s2)==mp.end()) mp[s2]=++tot,name[tot]=s2;
            a[i]=mp[s1];b[i]=mp[s2];
            od[a[i]]++;id[b[i]]++;
            add(a[i],b[i]); 
        }
        if(Flag) { cout<<endl;return 0;}                         //只有单个字母,坑了我好久 
        int S=1,c1=0,c2=0;
        for(i=1;i<=tot;i++){
            if(od[i]-id[i]==1) c1++,S=i;
            else if(od[i]-id[i]==-1) c2++;
            else if(od[i]-id[i]!=0) c1=3;
        }
        if(!((c1==0&&c2==0)||(c1==1&&c2==1)))  cout<<"NO"<<endl;//不满足欧拉路 
        else{
              dfs(S); 
              if(num!=n+1) cout<<"NO"<<endl;                    //不连通(也可以用并查集做) 
              else {
                 cout<<name[S];
                 for(i=num-1;i>=1;i--) cout<<name[path[i]][L-2];
              }
        }
        return 0;
    }
  • 相关阅读:
    URAL 2046 A
    URAL 2056 Scholarship 水题
    Codeforces Gym 100286I iSharp 水题
    Codeforces Gym H. Hell on the Markets 贪心
    Codeforces Gym 100286G Giant Screen 水题
    Codeforces Gym 100286B Blind Walk DFS
    Codeforces Gym 100286F Problem F. Fibonacci System 数位DP
    Codeforces Gym 100286A. Aerodynamics 计算几何 求二维凸包面积
    Codeforces Gym 100418K Cards 暴力打表
    Codeforces Gym 100418J Lucky tickets 数位DP
  • 原文地址:https://www.cnblogs.com/hua-dong/p/8133957.html
Copyright © 2011-2022 走看看