poj 2237(Catenyms)

2 篇文章 0 订阅
2 篇文章 0 订阅
 

这道题是,欧拉路和并查集结合起来的一道很恶心的题,最主要的难点在于,将这个模型抽象为欧拉路,已经应该用怎么样的存储方式。还有代码长了过后,变量的赋值一定要特别小心啊,我就是在一个地方把begin = i写成了begin - a; 于是就浪费了我好几个小时呢

Catenyms
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 5806 Accepted: 1503

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<string>
#include<cstdio>
#include<algorithm>

#define MAXN  1010
#define len 30
using namespace std;

char str[MAXN][len];
char str1[MAXN][len];
int father[len], n, changdu;
struct orer{
    int from, to, visit;
}oulaa[MAXN];

int cmp(const void *a, const void *b){
    return strcmp((char *)a, (char *)b);
}

int find(int x){
    int i,j;
    i = x;
    while(x != father[x])  x = father[x];
    while(i != x){//完成状态压缩
        j = father[i];
        father[i] = x;
        i = j;
    }
    return x;
}

void merge(int a, int b){
    int x = find(a);
    int y = find(b);
    father[x] = y;
}

void eurlar(int start,int size){
	for(int i=1;i<=size;i++)
	{
		if(!oulaa[i].visit && oulaa[i].from==start)
		{
			oulaa[i].visit = 1;
			eurlar(oulaa[i].to, size);
			strcpy(str1[++changdu],str[i]);
		}
	}
}
int main(){
    int t, in_out,a, b,begin, flag, in[len], out[len], used[len];
    scanf("%d", &t);
    while(t--){
        //printf("t : %d\n", t);
        memset(in,0,sizeof(in));
        memset(out,0,sizeof(out));
        memset(used, 0, sizeof(used));
        scanf("%d", &n);
        if(n<3){printf("***");printf("\n");continue;}
        in_out = 0;
        for(int i = 1; i <= n; i++){
            scanf("%s", str[i]);
        }
        for(int i = 1; i <= 26; i++){
            father[i] = i;
        }
        qsort(str+1, n, sizeof(str[0]), cmp);
        for(int i = 1; i <= n; i++){
            a = str[i][0] - 'a' + 1;
            b = str[i][strlen(str[i]) - 1] - 'a' + 1;
            oulaa[i].from = a;
            oulaa[i].to = b;
            oulaa[i].visit = 0;
            in[b]++;
            out[a]++;
            merge(a,b);
            used[a] = 1;
            used[b] = 1;
        }
        /*
        for(int  i = 1; i <= 26; i++){
            if(in[i] != out[i])
                in_out++;
        }
        if(in_out > 2){
            printf("***\n");
            continue;
        }*/
        a = 0;
        b = 0;
        for(int i = 1; i<= 26; i++){
            if(father[i] == i && used[i])
                b++;
        }
        if(b > 1){
            printf("***\n");
            continue;
        }
        a = 0,b = 0,flag = 0;
        for(int i = 1; i <= 26; i++){
            if(in[i] == out[i])  continue;
            else if(in[i] - 1 == out[i])  a++;
            else if(in[i] + 1 == out[i])  b++;
            else {
                flag = 1;
                break;
            }

        }
        if(flag == 1 || a > 1 || b > 1 || a != b){
            printf("***\n");
            continue;
        }
        begin = 1;
        changdu = 0;
        if(a == 1){
            for(int i = 1; i <= n;i++){
                if(out[oulaa[i].from] - in[oulaa[i].from] == 1){
                    begin = i;
                    break;
                }
            }
        }
        eurlar(oulaa[begin].from, n);
        for(int i = changdu; i > 1; i--){
            printf("%s.", str1[i]);
        }
        printf("%s\n", str1[1]);
    }
    return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值