spojPlay on Words

题意:给出几个词语,问能不能接龙。

一开始猜只要所有字母连通,并且只有一个字母出现在开头次数为奇,一个字母末尾为奇,其它偶,就行。后来发现全为偶也行。而且条件也不对,比如ac,ac,ac就不行。实际上是一个字母在开头的次数比在末尾的次数多1,一个少1.

//#pragma comment(linker,"/STACK:1024000000,1024000000") 
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<vector>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<algorithm>
#include <stack>
using namespace std;
typedef long long lon;
const lon SZ=26,INF=0x7FFFFFFF;
int arr[SZ],in[SZ],out[SZ];

void init()
{
    for(int i=0;i<SZ;++i)arr[i]=i;
}

int find(int x)
{
    return arr[x]==x?x:arr[x]=find(arr[x]);
}

void adj(int x,int y)
{
    int rtx=find(x),rty=find(y);
    arr[rtx]=rty;
}

bool apr[26];

bool in_the_same_set(vector<string> &vct)
{
    init();
    memset(apr,0,sizeof(apr));
    for(int i=0;i<vct.size();++i)
    {
        int a=vct[i][0]-'a';
        int b=vct[i][vct[i].size()-1]-'a';
        apr[a]=apr[b]=1;
        adj(a,b);
    }
    int rt=-1;
    for(int i=0;i<26;++i)
    {
        if(apr[i])
        {
            if(rt==-1)rt=find(i);
            else
            {
                if(find(i)!=rt)return 0;
            }
        }
    }
    return 1;
}

bool work()
{
    memset(in,0,sizeof(in));
    memset(out,0,sizeof(out));
    int n;
    cin>>n;
    vector<string> vct;
    for(int i=0;i<n;++i)
    {
        string str;
        cin>>str;
        vct.push_back(str);
        ++in[str[0]-'a'];
        ++out[str[str.size()-1]-'a'];
    }
    int head=0,tail=0,nh=0,nt=0;
    for(int i=0;i<26;++i)
    {
        if(in[i]==out[i]);
        else if(in[i]>out[i])
        {
            if(in[i]==out[i]+1)head=i,++nh;
            else return 0;
        }
        else
        {
            if(out[i]==in[i]+1)tail=i,++nt;
            else return 0;
        }
        //if(in[i]&1)
        //if(out[i]&1)
    }
    //cout<<" "<<nh<<" "<<nt<<endl;
    if(nh+nt>2)return 0;
    else
    {
        return in_the_same_set(vct);
    }
}

int main()
{
    std::ios::sync_with_stdio(0);
    //freopen("d:\\1.txt","w",stdout); 
    lon casenum;
    cin>>casenum;
    for(lon time=1;time<=casenum;++time)
    //for(;scanf("%d",&n)!=EOF;)
    {
        if(work())cout<<"Ordering is possible."<<endl;
        else cout<<"The door cannot be opened."<<endl;
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/gaudar/p/9750408.html