题解:SP41 WORDS1 - Play on Words

套路的欧拉回路题。

思路

我们假如把一个字符串看成一个点,两个字符串可以拼接就意味着在它们之间添加有向边,则我们只需在建成的图上找欧拉路就可以了。

例如下面的样例:

5
rrharil
luminescence
enginestart
technopolis
small

假如我们用 1155 把这些串任意编号,则建出来的图是这样的:

不难发现图上面存在一条 1234521\to2\to3\to4\to5\to2 的欧拉路,于是有解。

但是这样做的复杂度是 n2n^2 级别的。

考虑优化。

我们发现中间的这些字母都是无用的,只有头尾两个字母有用。

假如我们现在手中有一个 rrharil 的串,意味着我们下一步可以走到任一个以 l 开头的串,也意味着我们上一次用了一个以 r 结尾的串(除非 rrharil 是整个拼接的起点)。

于是我们可以从上一次要求以 r 开头转移到这一次以 l 开头。就是在 rl 之间连边。

也就是:我们对于一个字符串,从它的第一个字符到最后一个字符连有向边。一条边就代表一个字符串,如果可以走过每条边,就存在答案。

走过每条边,这就是欧拉路。

回忆一下欧拉路的判定(有向图):除起点、终点、入度等于出度。起点入度比出度小 11。终点入度比出度大 11

然后就做完了。记得判断图是否连通(如果 rl 不连通,则从 r 不可能走到 l)。判断连通并查集就行。

代码

#include<bits/stdc++.h>
using namespace std;
int T,n,cd[27],rd[27],fa[27];
string s;
int getint(char ch){
	return int(ch-'a')+1;
}
char rechar(int ch){
	return char(ch+'a'-1);
}
int findd(int now){
	if(fa[now]==now)return now;
	return fa[now]=findd(fa[now]);
}
void vnion(int u,int v){
	u=findd(u);
	v=findd(v);
	if(u==v)return;
	fa[u]=v;
}
int main(){
	scanf("%d",&T);
	while(T--){
		scanf("%d",&n);
		memset(cd,0,sizeof(cd));
		memset(rd,0,sizeof(rd));
		for(int i=1;i<=26;i++)fa[i]=i;
		for(int i=1;i<=n;i++){
			cin>>s;
			cd[getint(s[0])]++;
			rd[getint(s[s.length()-1])]++;
			vnion(getint(s[0]),getint(s[s.length()-1]));
		}
		int ji=-1;
		for(int i=1;i<=26;i++){
//			printf("%c %d\n",rechar(i),findd(i));
			if(cd[i]!=0||rd[i]!=0){
				if(ji==-1)ji=findd(i);
				else if(findd(i)!=ji){
					printf("The door cannot be opened.\n");
					ji=-2;
					break;
				}
			}
		}
		if(ji==-2)continue;
		int s=-1,t=-1;
		for(int i=1;i<=26;i++){
			if(cd[i]==rd[i])continue;
			if(cd[i]>rd[i]+1||cd[i]+1<rd[i]){
				printf("The door cannot be opened.\n");
				ji=-3;
				break;
			}
			if(cd[i]==rd[i]+1){
				if(s==-1)s=i;
				else{
					printf("The door cannot be opened.\n");
					ji=-3;
					break;
				}
			}
			if(rd[i]==cd[i]+1){
				if(t==-1)t=i;
				else{
					printf("The door cannot be opened.\n");
					ji=-3;
					break;
				}
			}
		}
		if(ji==-3)continue;
		printf("Ordering is possible.\n");
	}
	return 0;
}
posted @   Weslie_qwq  阅读(2)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示