• 单词游戏


    https://loj.ac/problem/10106

    题目描述

      给出(n)个单词,问能否完成所有单词的单词接龙。

    思路

      如果以单词为节点,条件为边建图,我们就要在图上求是否存在一条哈密尔顿道路,这显然难以实现。我们考虑以单词为边,以字母为节点,那么题目就相当于在图上求一条欧拉道路,但我们并不知道图是否是一张连通图,非连通图显然无法找到一条欧拉路径。所以我们还要再尝试找一遍欧拉路径来判断是否连通。而找欧拉路径容易造成栈溢出,所以我们可以递归改循环。当然用并查集判连通性也可以。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    const int N=30,M=1e5+10;
    
    int nxt[M],to[M],tot,head[N];
    void add_edge(int x,int y)
    {
        nxt[++tot]=head[x];
        head[x]=tot;
        to[tot]=y;
    }
    
    int read()
    {
        int res=0,w=1;
        char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){res=(res<<3)+(res<<1)+ch-'0';ch=getchar();}
        return res*w;
    }
    
    int st[M],top;
    bool vis[M];
    void euler(int s)
    {
        st[++top]=s;
        while(top>=1)
        {
            int x=st[top],i=head[x];
            while(i&&vis[i])i=nxt[i];
            if(i)
            {
                st[++top]=to[i];
                head[x]=nxt[i];
                vis[i]=1;
            }
            else
                --top;
        }
    }
    
    char s[1100];
    int in[30],out[30];
    int main() 
    {
        int t=read();
        while(t--)
        {
            memset(head,0,sizeof(head));
            memset(vis,0,sizeof(vis));
            memset(in,0,sizeof(in));
            memset(out,0,sizeof(out));
            top=0;tot=0;
            int n=read();
            for(int i=1;i<=n;i++)
            {
                scanf(" %s",s);
                int x=s[0]-'a'+1,y=s[strlen(s)-1]-'a'+1;
    //            cout<<x<<' '<<y<<endl;
                in[y]++;out[x]++;
                add_edge(x,y);
            }
            bool f=1;
            int cnt1=0,cnt2=0,st=1;
            for(int i=1;i<=26;i++)
            {
                if(in[i]-out[i]==1)cnt1++;
                else if(out[i]-in[i]==1)cnt2++,st=i;
                else if(out[i]!=in[i])f=0;
                if(cnt1>1||cnt2>1)f=0;
            }
            euler(st);
            for(int i=1;i<=n;i++)
                if(!vis[i]){f=0;break ;}
            if(f)printf("Ordering is possible.
    ");
            else printf("The door cannot be opened.
    ");
        } 
    }
    
  • 相关阅读:
    [Canvas]RPG游戏雏形 (地图加载,英雄出现并移动)
    [Canvas]计时表/秒表
    [Canvas]新版箴言钟表
    [Canvas]用透明PNG图在背景上画前景能不遮挡背景
    [Canvas]动态背景
    [Canvas]更多的球
    [Canvas]碰撞球 增加小球间碰撞检测
    [Canvas]碰撞球
    [Canvas]越来越近的女孩
    [Canvas]走近的女孩
  • 原文地址:https://www.cnblogs.com/fangbozhen/p/11752952.html
Copyright © 2020-2023  润新知