HDOJ 1116 Play on Words

本文探讨了如何通过欧拉回路的判断来解决HDOJ1116问题,即通过字母收尾相接的顺序找到能够打开门的口令。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1116

题意:给我们一些单词,问我们可不可以找到字母收尾相接的顺序得到口令打开门,通俗一点就是一个单词的结尾和下一个单词的开头相接可不可以把所有的单词给遍历完。

其实这题就是相当于一个欧拉回路的判断,因为一个单词的收尾关系是定的,实际上给的我们是一个有向图,首先我们得确定这个图是否联通,判断的方法可以借助并查集,在判断完联通后便统计每个出现过的字母的入度和出度,对于一个有向图,满足条件的可能有两种,成环的话所有点的出度 == 入度,成链的话在首端的入度+1 == 出度,在尾端入度 == 出度+1。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
const int maxn = 30;
int set[maxn],in[maxn],out[maxn];
char str[1005];
bool vis[maxn];
int find(int x)
{
	int r = x;
	while(set[r] != r)
		r = set[r];
	return r;
}
void merge(int x,int y)
{
	int a,b;
	a = find(x);
	b = find(y);
	if(a != b)
		set[a] = set[b];
}
int main()
{
	int T;
	scanf("%d",&T);
	while(T--)
	{
		memset(in,0,sizeof(in));
		memset(out,0,sizeof(out));
		memset(vis,0,sizeof(vis));
		for(int i=0; i<26; i++) set[i] = i;
		int n;
		scanf("%d",&n);
		for(int i=0; i<n; i++)
		{
			scanf("%s",str);
			int s = str[0]-'a';
			int e = str[strlen(str)-1]-'a';
			merge(s,e);
			out[s]++;
			in[e]++;
			vis[s] = vis[e] = 1;
		}
		int root = 0, innum = 0, outnum = 0,flag = 0;
		for(int i=0; i<26; i++)
			if(vis[i])
			{
				if(set[i] == i)
					root++;
				if(in[i] != out[i])
				{
					if(in[i] == out[i]+1)
						innum++;
					else if(out[i] == in[i]+1)
						outnum++;
					else flag = 1;
				}
				if(root > 1)
				{
					flag = 1;
					break;
				}
			}
		if(flag)
			printf("The door cannot be opened.\n");
		else if((innum == 1 && outnum == 1) || (innum == 0 && outnum == 0))
			printf("Ordering is possible.\n");
		else printf("The door cannot be opened.\n");
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值