POJ 2337 Catenyms

题目链接 : POJ2337

Catenyms
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 8095 Accepted: 2130

Description

A catenym is a pair of words separated by a period such that the last letter of the first word is the same as the last letter of the second. For example, the following are catenyms: 
dog.gopher

gopher.rat

rat.tiger

aloha.aloha

arachnid.dog

A compound catenym is a sequence of three or more words separated by periods such that each adjacent pair of words forms a catenym. For example, 

aloha.aloha.arachnid.dog.gopher.rat.tiger

Given a dictionary of lower case words, you are to find a compound catenym that contains each of the words exactly once.

Input

The first line of standard input contains t, the number of test cases. Each test case begins with 3 <= n <= 1000 - the number of words in the dictionary. n distinct dictionary words follow; each word is a string of between 1 and 20 lowercase letters on a line by itself.

Output

For each test case, output a line giving the lexicographically least compound catenym that contains each dictionary word exactly once. Output "***" if there is no solution.

Sample Input

2
6
aloha
arachnid
dog
gopher
rat
tiger
3
oak
maple
elm

Sample Output

aloha.arachnid.dog.gopher.rat.tiger
***

Source

 

欧拉路径~

 

#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<string>
#include<vector>
#include<map>
#include<set>
#include<queue>
using namespace std;


vector<pair<int,int> > gra[30];
char lib[1005][30];
int ind[1005],in[30],out[30];
int c[30];
int ans[10005],h;
bool cmp(int a,int b)
{
    return (strcmp(lib[b],lib[a])<0)?0:1;
}
void eur(int s)
{
    for(int i=0;i<gra[s].size();i++)
        if(gra[s][i].second<5555)
        {
            gra[s][i].second+=10000;
            eur(gra[s][i].first);
        }
    ans[h++]=s;
}
void dfs(int s)
{
    if(s==0) return;
    int x=ans[s],y;
    for(int i=0;i<gra[x].size();i++)
    {
        if(gra[x][i].first==ans[s-1] && gra[x][i].second)
        {
            if(s!=1) printf("%s.",lib[gra[x][i].second-10000]);
            else printf("%s\n",lib[gra[x][i].second-10000]);
            gra[x][i].second=0;
            dfs(s-1);
        }
    }
}
int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
    {
        int m;
        scanf("%d",&m);
        for(int i=0;i<26;i++)
            gra[i].clear();
        for(int i=0;i<m;i++)
            scanf("%s",lib[i]),ind[i]=i;
        sort(ind,ind+m,cmp);
        int len,j;
        memset(in,0,sizeof(in));
        memset(out,0,sizeof(out));
        for(int i=0;i<m;i++)
        {
            j=ind[i];
            len=strlen(lib[j])-1;
            gra[lib[j][0]-'a'].push_back(make_pair(lib[j][len]-'a',j));
            in[lib[j][len]-'a']++;out[lib[j][0]-'a']++;
        }
        int ty=0,fa=0;
        for(int i=0;i<26;i++)
        {
            if(abs(in[i]-out[i])>1)
            {
                ty=2;
                break;
            }
            else if(abs(in[i]-out[i])==1) ty=1,c[fa++]=i;
        }
        if(fa>2) ty=2;
        if(ty==0)
        {
            h=0;
            eur(lib[ind[0]][0]-'a');
            if(h-1!=m) printf("***\n");
            else dfs(h-1);

        }
        else if(ty==1)
        {
            int s=c[0];
            if(in[c[0]]-out[c[0]]>0) s=c[1];
            h=0;
            eur(s);
            if(h-1!=m) printf("***\n");
            else dfs(h-1);
        }
        else printf("***\n");
    }
	return 0;
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值