10129 - Play on Words

首先将单词看成是连接首字母和尾字母的有向边,然后在建立图的过程当中记录每个字母的入度和出度。当无向图建立好了之后,首先利用队列进行DFS遍历,判断图是否联通,如果图不联通则直接否定,如果图是联通的,那么逐个分析每个顶点的入度和出度只差,只有两种情况可以接收:第一种是所有顶点的出度和入度都相等,第二种情况是仅仅存在两个顶点的出度不等于入度,并且其中一个顶点的出度减去入度为1,另外一个顶点的入度减去出度为1,同时要保证出度与入度之间没有其他差值的情况存在即可,具体实现见如下源代码:

#include<iostream>
#include<vector>
#include<string>
#include<set>
#include<stack>
#include<queue>
#include<map>
#include<algorithm>
#include<cmath>
#include<iomanip>
#include<cstring>
#include<sstream>
using namespace std;

int T;

int main(){
	cin >> T;
	while (T--){
		int in[26], out[26];
		memset(in,0,sizeof(in));
		memset(out,0,sizeof(out));
		int N;
		cin >> N;
		int area[26][26];
		set<char> st;
		bool visit[26];
		memset(visit,false,sizeof(visit));
		memset(area,0,sizeof(area));
		for (int i = 0; i < N; i++){
			string s;
			cin >> s;
			st.insert(s[0]);
			st.insert(s[s.size()-1]);
			int index1 = s[0] - 'a';
			int index2 = s[s.size() - 1] - 'a';
			out[index1]++;
			in[index2]++;
			area[index1][index2] = 1;
			area[index2][index1] = 1;
		}
		int start = (*st.begin()) - 'a';
		queue<int> q;
		q.push(start);
		visit[start] = true;
		int amount = 0;
		while (!q.empty()){
			int index = q.front();
			q.pop();
			amount++;
			for (int i = 0; i < 26; i++){
				if (area[index][i] && !visit[i]){
					q.push(i);
					visit[i] = true;
				}
			}
		}
		if (amount != st.size()){
			cout << "The door cannot be opened." << endl;
		}
		else{
			int first = 0;
			int second = 0;
			int other = 0;
			for (int i = 0; i < 26; i++){
				if (out[i] - in[i] == 1) first++;
				else if (in[i] - out[i] == 1) second++;
				else if (abs(in[i] - out[i]) != 0) other++;
			}
			if ((first == 1 && second == 1 && other == 0) || (first == 0 && second == 0 && other == 0))
				cout << "Ordering is possible." << endl;
			else cout << "The door cannot be opened." << endl;
		}
	}
	//system("pause");
	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值