HDU 1116 Play on Words

来源:互联网 发布:网络推销是什么工作 编辑:程序博客网 时间:2024/06/06 07:21

题目大意:给你一些英文单词,判断所有单词能不能连成一串,类似成语接龙的意思。但是如果有多个重复的单词时,也必须满足这样的条件才能算YES。否则都是不可能的情况

题解:利用并查集判断是否具有联通分量,在判断每个单词在首位与末位是否次数一致或差1

#include<cstdio>#include<cstring>#include<cmath>#include<ctime>#include<algorithm>#include <iostream>#include <queue>#include <stack>#include <vector>#include <map>#include <set>#define INF 0x3f3f3f3f#define maxn 1000100#define mem(a) memset(a,0,sizeof(a))using namespace std;typedef long long ll;int fa[30],vis[30];int Find(int x){    return x == fa[x]?x:Find(fa[x]);}int main(){    int t;    scanf("%d",&t);    while(t--)    {        int n;        scanf("%d",&n);        int num1[30] = {0},num2[30] = {0};        char s[1010];        for(int i = 0; i < 30; i++)            fa[i] = i;        mem(vis);        for(int i = 0; i < n; i++)        {            scanf("%s",s);            num1[s[0]-'a']++;            num2[s[strlen(s)-1]-'a']++;            fa[s[0]-'a'] = fa[s[strlen(s)-1]-'a'] = Find(s[0]-'a');            vis[s[0]-'a'] = vis[s[strlen(s)-1]-'a'] = 1;        }        int flag = 1,flag1 = 0,flag2 = 0,k = 0;        for(int i = 0; i < 30; i++)            if(vis[i] && i == fa[i])                k++;        if(k > 1)            flag = 0;        for(int i = 0; i < 30; i++)        {            if(num1[i] > num2[i])            {                if(num1[i] - num2[i] > 1 || (num1[i]-num2[i] == 1 && flag1))                {                    flag = 0;                    break;                }                else                    flag1 = 1;            }            else if(num1[i] < num2[i])            {                if(num2[i] - num1[i] > 1 || (num2[i]-num1[i] == 1 && flag2))                {                    flag = 0;                    break;                }                else                    flag2 = 1;            }        }        if(flag)            printf("Ordering is possible.\n");        else            printf("The door cannot be opened.\n");    }    return 0;}


0 0
原创粉丝点击