单词游戏题解

   日期:2020-08-21     浏览:108    评论:0    
核心提示:题目:来自 ICPC CERC 1999/2000,有改动。有NNN个盘子,每个盘子上写着一个仅由小写字母组成的英文单词。你需要给这些盘子安排一个合适的顺序,使得相邻两个盘子中,前一个盘子上单词的末字母等于后一个盘子上单词的首字母。请你编写一个程序,判断是否能达到这一要求。如果能,请给出一个合适的顺序。输入:多组数据。第一行给出数据组数TTT ,每组数据第一行给出盘子数量NNN ,接下去NNN 行给出小写字母字符串,一种字符串可能出现多次。输出:若存在一组合法解输出Ordering is po

题目:

来自 ICPC CERC 1999/2000,有改动。

N N N个盘子,每个盘子上写着一个仅由小写字母组成的英文单词。你需要给这些盘子安排一个合适的顺序,使得相邻两个盘子中,前一个盘子上单词的末字母等于后一个盘子上单词的首字母。请你编写一个程序,判断是否能达到这一要求。如果能,请给出一个合适的顺序。

输入:

多组数据。第一行给出数据组数 T T T ,每组数据第一行给出盘子数量 N N N ,接下去 N N N 行给出小写字母字符串,一种字符串可能出现多次。

输出:

若存在一组合法解输出Ordering is possible.,否则输出The door cannot be opened.

样例输入:

3
2
acm
ibm
3
acm
malform
mouse
2
ok
ok

样例输出:

The door cannot be opened.
Ordering is possible.
The door cannot be opened.

题解:

题意是将每个盘子连接起来,要满足相邻两个盘子的末尾和起点相同。
初始思路:将盘子看成点,如果找到两两盘子首末字母相同就建一条边,最后走一遍欧拉通路。但这显然是错的,因为欧拉通路要经过每一条边且不能重复,那麽只要两盘子建了边,它都要算,但题目是只要相邻两盘子满足条件即可,所以这种方法会跑重。
正解:
我们可以用每个盘子首末字母看成点,在每个盘子的首末字母间建一条边(即可以看成以每个盘子为边),最后对所有盘子的首末字母跑一遍欧拉通路即可,如果可以连通,即每条边(盘子)都可以连上,那么就满足题意,反之不满足。
如这一组:

3
acm
malform
mouse

有图:


它是欧拉通路所以满足。
最后还要判一遍这里面的点连不连通,所以可以用并查集,如果判到两个字母,那么就并到一起,最后判一遍即可

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;
const int MAXN = 100005;
int t, n, ru[MAXN], tot, chu[MAXN], fa[30];
string h;

int Find_Set(int x) {
	if(fa[x] == x) {
		return x;
	}
	return fa[x] = Find_Set(fa[x]);
}

int main() {
	scanf("%d", &t);
	while (t--) {
		memset(chu, 0, sizeof(chu));
		memset(ru, 0, sizeof(ru));
		scanf("%d", &n);
		for(int i = 1;i <= 26; i++) fa[i] = i;
		for (int i = 1;i <= n; i++) {
			cin>>h;
			int siz = h.size();
			int x1 = h[0] - 'a' + 1, x2 = h[siz - 1] - 'a' + 1;
			chu[x1]++;
			ru[x2]++; 
			int u = Find_Set(x1), v = Find_Set(x2);
			if(u != v) {
				fa[v] = u;
			}
		}
		int uu = 0;
		for(int i = 1; i <= 26; i++) {
			if((chu[i] || ru[i]) && fa[i] == i) {
				uu++;
			}
		}
		if(uu == 1) {
			int ans = 0, ans1 = 0;
			bool flag = 1;
			for(int i = 1;i <= 26; i++) {
				if(chu[i] != ru[i]) {
					if(chu[i] - ru[i] == 1)  {
						ans++;
					}
					else if(ru[i] - chu[i] == 1) {
						ans1++;
					}
					else{
						flag = 0;
						break;
					}
				}	
			}
			if(flag && ans1 <= 1 && ans <= 1) {
				printf("Ordering is possible.\n");
			}
			else{
				printf("The door cannot be opened.\n");
			}	
		}
		else{
			printf("The door cannot be opened.\n");
		}
	}
	return 0;
}
 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服