• 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;
    }
  • 相关阅读:
    Android操作系统中11种传感器的介绍【转】
    陀螺仪、加速计、磁力计【转】
    【转】在ubuntu环境下搭建svn server遇到的一些问题
    【转】Ubuntu下搭建SVN环境-Apache
    【转】Java ConcurrentModificationException 异常分析与解决方案--还不错
    【转】ConcurrentModificationException异常解决办法 --不错
    【转】Java ConcurrentModificationException异常原因和解决方法
    【转】 为SeekBar滑块设置固定值以及自定义Seekbar,progressbar样式--不错
    【转】Android自定义Adapter的ListView的思路及代码
    【转】如何开发苹果iOS操作平台下的应用程序?
  • 原文地址:https://www.cnblogs.com/hua-dong/p/8133957.html
Copyright © 2020-2023  润新知