`
Jianquan
  • 浏览: 19735 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

UVa 10129 Play on Words

    博客分类:
  • UVa
阅读更多

题目:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=105&page=show_problem&problem=1070

题目大意是给你一串单词,判断能否连接成一条长串,两个单词能够连接的条件是后一个单词的首字母与前一个单词的尾字母相同(单词至少有2个字母)。单词仅由小写字母组成。

这个题目对于我们新手来说还是有难度的。首先这是一个图论问题,我们把单词看作是点,单词之间的连接关系看作是边。题目所给的数据规模:单词的个数到达10万,所以我们不能把每一个单词看作一个点,而是把相同的单词看左是一个点。实际上,对于每一个单词,我们只需要知道它的首字母和尾字母就可以了,中间并不管,那么首字母和尾字母相同就是相同的单词,那么这样不同的单词最多只有26*26=676个了。

把单词连成一条长串,实际上是有向图的欧拉道路的打印结果。那么根据有向图里面欧拉道路的结论,除了起点和终点以外,其它的点的入度等于出度,起点的入度比出度少1,终点的出度比入度少1。对于这道题来说,我们只需要统计以某个字母为开头和结尾单词的个数,比方说,我们统计以m结尾的单词的个数(记为end)以及以m开头的单词的个数(记为front),对于a~z都要统计。我们仅仅允许出现1次end>front和1次front>end,其余情况end==front(所有的end都等于front也是可以的)。满足上述条件的就可以连成长串,否则不可以。当然,存在欧拉道路首先要连通,我们可以先搜索一次判断是否连通,这里的连通是指把相同的单词看成一个点,把有向图的方向忽略,当做无向图,判断是否连通。

#include<iostream>
#include<string>
#include<cstring>
#define MAXN 676
using namespace std;

int word[MAXN],vis[MAXN];//word数组保存不同的单词的数目,首字母*26+尾字母作为下标

void dfs(int cur)
{
	for(int i=0;i<MAXN;i++)
		if(word[i]&&!vis[i]&&(cur%26==i/26||cur/26==i%26))
		{
			vis[i]=1;
			dfs(i);
		}
}
int main()
{
	//freopen("in.txt","r",stdin);
	int i,N,T;
	string tmp;
	cin>>T;
	while(T--)
	{
		int first;
		cin>>N;
		memset(word,0,sizeof(word));
		for(i=0;i<N;i++)
		{
			int num,last;
			cin>>tmp;//输入单词
			last=tmp.length()-1;
			num=(tmp[0]-'a')*26+(tmp[last]-'a');//提取首尾字母,计算对应的下标
			word[num]++;
			if(i==0) first=num;//记下第一个单词,用于搜索
		}
		//先搜索,判断是否连通
		memset(vis,0,sizeof(vis));
		vis[first]=1;
		dfs(first);
		int ok=1;
		for(i=0;i<MAXN;i++)
			if(word[i]&&!vis[i])
			{ok=0;break;}
		if(ok==0)//如果不连通则一定不可以连成长串
		{
			cout<<"The door cannot be opened."<<endl;
			continue;
		}
		//再判断是否存在欧拉道路
		int front[26]={0},end[26]={0};
		for(i=0;i<MAXN;i++)
		{
			front[i/26]+=word[i];
			end[i%26]+=word[i];
		}
		int flag1=0,flag2=0;
		ok=1;
		for(i=0;i<26;i++)
		{
			if(front[i]==end[i]) continue;
			else if(front[i]-end[i]==1)
				flag1++;
			else if(end[i]-front[i]==1)
				flag2++;
			else {ok=0;break;}
			if(flag1>1||flag2>1) {ok=0;break;}
		}
		if(ok&&(flag1==0&&flag2==0||flag1==1&&flag2==1))
			cout<<"Ordering is possible."<<endl;
		else
			cout<<"The door cannot be opened."<<endl;
	}
	return 0;
}
 

 

分享到:
评论

相关推荐

    UVa Online Judge部分题目代码

    UVa Online Judge是一个著名的在线编程竞赛平台,它提供了大量的算法问题供程序员们挑战,以提升他们的编程技巧和算法理解能力。这个压缩包包含了在UVa平台上部分题目的解答,是学习和参考的好资源。让我们详细了解...

    UVa Online Judge 10944 Accepted Code

    UVa Online Judge 10944 Accepted Code

    开源项目-codingsince1985-UVa#uva-online-judge-solutions-in-golang.zip

    开源项目-codingsince1985-UVa#uva-online-judge-solutions-in-golang.zip,两年来每天都在解决一个uva在线裁判问题,算起来…

    uva272 uva272 uva272

    标题中的"uva272 uva272 uva272"和描述中的"uva272"指的是UVA(University of Virginia)在线判题系统的第272题,这通常与编程竞赛和算法挑战有关。该题目的标签为"算法",意味着我们需要解决一个与计算机算法设计和...

    uvaoj 习题题目

    在编程学习和竞赛中,UVa Online Judge(简称UVa或OJ)是一个广受欢迎的在线评测系统,它为程序员提供了大量练习题目,涵盖算法、数据结构、数学等多个领域。通过解决这些题目,开发者可以提升自己的编程技能,锻炼...

    UVA_示例代码

    UVA Online Judge(简称UVA OJ)是这个平台的实现,支持多种编程语言,包括C、C++、Java等,用户可以提交代码并实时获取运行结果和评测反馈。 这个名为“UVA_示例代码”的压缩包包含了UVA OJ系统中大量题目的示例...

    UVA题目大全

    【UVA题目大全】是面向ACM(国际大学生程序设计竞赛)参赛者和算法爱好者的一份宝贵资源。UVA(University of Victoria Algorithm)在线判题系统是世界上最早的在线编程竞赛平台之一,它提供了大量的编程题目供用户...

    uva最全ac代码

    【标题】"uva最全ac代码" 涉及的是在编程竞赛领域中的一个集锦,特别是针对UVA(University of Victoria Algorithm)在线判题系统的解决方案。UVA是全球最早的在线算法竞赛平台之一,吸引了众多程序员参与并提交代码...

    uva 200~299 22道题解 均accept

    这些文件是针对UVA(University of Virginia)在线判题系统的编程题目的解决方案,主要涵盖了编号为200至299的题目。UVA在线判题平台是一个著名的编程竞赛和练习平台,它提供了各种难度级别的算法和编程问题,旨在...

Global site tag (gtag.js) - Google Analytics