zoukankan      html  css  js  c++  java
  • POJ 2337 欧拉回路

    题意:
    如果给出的单词能够首尾相接,请按字典序输出单词,中间要加’.’
    否则输出三个”*”.
    思路:
    欧拉回路
    记得按字典序排序哦~
    加边的时候要倒着加。(邻接表遍历的时候是反着的)

    记得清空vis数组(因为这个无脑错误WA了好长时间。。。。。)

    随便搞搞 就能过了。 数据不是很强…

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    char s[1005][25];
    int first[60],next[1005],tot,top,v[1005];
    int cases,n,ansx,ansy,ansz,in[26],out[26],ans[1005];
    bool vis[1005],flag,VIS[26];
    struct node{char str[25];int length;}edge[1005];
    void add(int x,int y,int z){v[z]=y;next[z]=first[x];first[x]=z;}
    bool cmp(node x,node y){return strcmp(x.str,y.str)>0?0:1;}
    void dfs(int x){
        for(int i=first[x];~i;i=next[i])
            if(!vis[i]){
                VIS[v[i]]=1;
                vis[i]=1,dfs(v[i]);
                ans[++top]=i;
            }
    }
    int main(){
        scanf("%d",&cases);
        while(cases--){
            memset(first,-1,sizeof(first));
            memset(in,0,sizeof(in));
            memset(out,0,sizeof(out));
            memset(vis,0,sizeof(vis));
            memset(VIS,0,sizeof(VIS));
            flag=ansx=ansy=ansz=top=0;
            scanf("%d",&n);
            for(int i=1;i<=n;i++){
                scanf("%s",edge[i].str);
                edge[i].length=strlen(edge[i].str);
                out[edge[i].str[0]-'a']++;
                in[edge[i].str[edge[i].length-1]-'a']++;
            }
            sort(edge+1,edge+1+n,cmp);
            for(int i=n;i;i--)
                add(edge[i].str[0]-'a',edge[i].str[edge[i].length-1]-'a',i);
            for(int i=0;i<=25;i++){
                if(in[i]-out[i]==1)ansx++;
                else if(out[i]-in[i]==1)ansy++;
                else if(in[i]!=out[i])ansz++;
            }
            if(!ansz&&ansx==ansy&&(ansx==0||ansx==1)){
                int jy;
                if(ansx==1){
                    for(int i=0;i<26;i++)
                        if(out[i]-in[i]==1){jy=i;break;}
                }
                else{
                    for(int i=0;i<26;i++)
                        if(out[i]){jy=i;break;}
                }
                VIS[jy]=1;
                dfs(jy);
                for(int i=0;i<=25;i++)
                    if((in[i]||out[i])&&!VIS[i])flag=1;
            }
            else flag=1;
            if(!flag){
                for(int i=top;i>=2;i--)
                printf("%s.",edge[ans[i]].str);
                printf("%s
    ",edge[ans[1]].str);
            }
            else puts("***");
        }
    }

    这里写图片描述

  • 相关阅读:
    第六次上机作业
    NOIP2016 DAY1 T2天天爱跑步
    NOIP2009 T2 Hankson的趣味题
    NOIP2013 DAY2 T3火车运输
    线段树
    NOIP2012 DAY2 T2借教室
    NOIP2015 DAY2 T1跳石头
    NOIP2016 DAY2 T3 愤怒的小鸟
    文本编辑常用快捷键
    洛谷P1516 青蛙的约会
  • 原文地址:https://www.cnblogs.com/SiriusRen/p/6532393.html
Copyright © 2011-2022 走看看