SPOJ Play on Words
WORDS1 - Play on Words
Some of the secret doors contain a very interesting word puzzle. The team of archaeologists has to solve it to open that doors. Because there is no other way to open the doors, the puzzle is very important for us.
There is a large number of magnetic plates on every door. Every plate has one word written on it. The plates must be arranged into a sequence in such a way that every word begins with the same letter as the previous word ends. For example, the word acm'' can be followed by the word motorola''. Your task is to write a computer program that will read the list of words and determine whether it is possible to arrange all of the plates in a sequence (according to the given rule) and consequently to open the door.
Input
The input consists of T test cases. The number of them (T, equal to about 500) is given on the first line of the input file. Each test case begins with a line containing a single integer number N that indicates the number of plates (1 <= N <= 100000). Then exactly Nlines follow, each containing a single word. Each word contains at least two and at most 1000 lowercase characters, that means only letters 'a' through 'z' will appear in the word. The same word may appear several times in the list.
Output
Your program has to determine whether it is possible to arrange all the plates in a sequence such that the first letter of each word is equal to the last letter of the previous word. All the plates from the list must be used, each exactly once. The words mentioned several times must be used that number of times.
If there exists such an ordering of plates, your program should print the sentence "Ordering is possible.". Otherwise, output the sentence "The door cannot be opened.".
Example
Sample input: 3
2
acm
ibm
3
acm
malform
mouse
2
ok
ok Sample output: The door cannot be opened.
Ordering is possible.
The door cannot be opened.
-----------------------------------------------------
题目要求将所有单词排列成such that the first letter of each word is equal to the last letter of the previous word。这道题是典型的欧拉路径问题,这种问题分析起来还是有一定难度的。
我们考虑如何建图
将26个字母看成节点,将每个单词看成从其首字母向尾字母的有向边。
问题转换成判断有向图中是否存在一条欧拉路径。
-----------------------------------------------------
Solution
一个有向图存在欧拉路径的必要条件是:
每个节点的出度都等于入度
或
存在一个节点s,其入度比出度少1,存在一个节点t,其出度比入度多1
在前一种情况下若图中存在欧拉路径,那么起点和终点必然是同一点,而且任意出度不为0的节点都可作为起点,
在后一种情况下若图中存在欧拉路径,那s必然是起点,t必然是终点。
-----------------------------------------------------
但上述条件仅仅是必要条件,除此之外还要求图“连通”,
即要求从前面确定的起点出发可以走完所有边(这好像是废话)
其实前面的必要条件仅能快速判断出欧拉路径不存在的情况,
对于欧拉路径存在的情况仍然要通过遍历图中的边来确认。
------------------------------------------------------
下面考虑如何遍历有向图(可能存在重边、自环)中的边。
如果用vector<int> g[N存图的话不是很方便,而链式前向星是比较方便的
请特别注意下面代码中加粗的三行,并请考虑如果将那三行改成下面两种写法
有什么问题
void dfs(int u){
for(; ~head[u]; head[u]=E[head[u]].nt){
int &v=E[head[u]].to;
dfs(v);
}
}
void dfs(int u){
for(; ~head[u];){
int &v=E[head[u]].to;
head[u]=E[head[u]].nt;
dfs(v);
}
}
----------------------------------------------------------
Code
#include <bits/stdc++.h>
using namespace std;
char s[];
int in[], out[];
const int M(1e5+);
struct edge{
int to, nt;
}E[M];
int head[];
void dfs(int u){
for(; ~head[u];){
int v=E[head[u]].to; //this edge has been used
head[u]=E[head[u]].nt;
dfs(v);
}
}
bool solve(int n){
bool flag=true;
for(int i=; i<; i++)if(in[i]!=out[i]){flag=false; break;}
if(flag){
for(int i=; i<; i++) if(out[i]){dfs(i); break;}
for(int i=; i<; i++) if(~head[i]) return ;
return ;
}
int s=-, t=-;
for(int i=; i<; i++){
if(in[i]!=out[i]){
if(abs(in[i]-out[i])!=) return ;
if(in[i]>out[i]){
if(~t) return ;
t=i;
}
else if(in[i]<out[i]){
if(~s) return ;
s=i;
}
}
}
if(~s&&~t){
dfs(s);
for(int i=; i<; i++) if(~head[i]) return ;
return ;
}
return ;
}
int main(){
int T; scanf("%d", &T);
for(int n; T--;){
scanf("%d", &n);
memset(in, , sizeof(in));
memset(out, , sizeof(out));
memset(head, -, sizeof(head));
for(int len, u, v, id=, _=n; _--;){
scanf("%s", s);
len=strlen(s);
u=s[]-'a', v=s[len-]-'a';
out[u]++, in[v]++;
E[id]={v, head[u]}, head[u]=id++;
}
puts(solve(n)?"Ordering is possible.":"The door cannot be opened.");
}
}
SPOJ Play on Words的更多相关文章
- BZOJ 2588: Spoj 10628. Count on a tree [树上主席树]
2588: Spoj 10628. Count on a tree Time Limit: 12 Sec Memory Limit: 128 MBSubmit: 5217 Solved: 1233 ...
- SPOJ DQUERY D-query(主席树)
题目 Source http://www.spoj.com/problems/DQUERY/en/ Description Given a sequence of n numbers a1, a2, ...
- SPOJ GSS3 Can you answer these queries III[线段树]
SPOJ - GSS3 Can you answer these queries III Description You are given a sequence A of N (N <= 50 ...
- 【填坑向】spoj COT/bzoj2588 Count on a tree
这题是学主席树的时候就想写的,,, 但是当时没写(懒) 现在来填坑 = =日常调半天lca(考虑以后背板) 主席树还是蛮好写的,但是代码出现重复,不太好,导致调试的时候心里没底(虽然事实证明主席树部分 ...
- SPOJ bsubstr
题目大意:给你一个长度为n的字符串,求出所有不同长度的字符串出现的最大次数. n<=250000 如:abaaa 输出: 4 2 1 1 1 spoj上的时限卡的太严,必须使用O(N)的算法那才 ...
- 【SPOJ 7258】Lexicographical Substring Search
http://www.spoj.com/problems/SUBLEX/ 好难啊. 建出后缀自动机,然后在后缀自动机的每个状态上记录通过这个状态能走到的不同子串的数量.该状态能走到的所有状态的f值的和 ...
- 【SPOJ 1812】Longest Common Substring II
http://www.spoj.com/problems/LCS2/ 这道题想了好久. 做法是对第一个串建后缀自动机,然后用后面的串去匹配它,并在走过的状态上记录走到这个状态时的最长距离.每匹配完一个 ...
- 【SPOJ 8222】Substrings
http://www.spoj.com/problems/NSUBSTR/ clj课件里的例题 用结构体+指针写完模板后发现要访问所有的节点,改成数组会更方便些..于是改成了数组... 这道题重点是求 ...
- SPOJ GSS2 Can you answer these queries II
Time Limit: 1000MS Memory Limit: 1572864KB 64bit IO Format: %lld & %llu Description Being a ...
- SPOJ 3273
传送门: 这是一道treap的模板题,不要问我为什么一直在写模板题 依旧只放代码 Treap 版 //SPOJ 3273 //by Cydiater //2016.8.31 #include < ...
随机推荐
- WPF技巧-Canvas转为位图
转自:http://www.cnblogs.com/tmywu/archive/2010/09/14/1825650.html 在WPF中我们可以将Canvas当成一种画布,将Canvas中的控件当成 ...
- 【转】【C#】异常类 Exception 枚举所有类型的异常
一.基础 在C# 里,异常处理就是C# 为处理错误情况提供的一种机制.它为每种错误情况提供了定制的处理方式,并且把标识错误的代码与处理错误的代码分离开来. 对.NET类来说,一般的 异常类System ...
- xp-win7-win8的基础到精通教程-系统优化减肥教程-windos装mac
是否还在使用别人封装的系统?是否还在担心下载后的系统是有病毒的?还在为 安装好新系统后,里面安装的软件全是自己不需要的?担心流氓软件绑定浏览器主页?担心 系统重装后,自己所有的编程软件都需要重新安装? ...
- [CareerCup] 4.2 Route between Two Nodes in Directed Graph 有向图中两点的路径
4.2 Given a directed graph, design an algorithm to find out whether there is a route between two nod ...
- Linux(9.21-9.27)学习笔记
一.Vim的基本操作. Normal模式下 1.h 键 向左移动光标 2. j 键 向下移动光标 3. k 键 向上移动光标 4. l键 向右移动光标 5.x 键 删除光标所在位置的 ...
- Android--保持加速度传感器在屏幕关闭后运行
由于写论文需要,需要用手机加速度采集数据,关于android加速度传感器的介绍网上一抓一大把,但大多都是大同小异,跟官网文档差不多.自己写了个取加速度传感器的APK,发现数据有点不对劲,原理屏幕一关后 ...
- javascript中prototype、constructor以及__proto__之间的三角关系
三者暧昧关系简单整理 在javascript中,prototype.constructor以及__proto__之间有着“著名”的剪不断理还乱的三角关系,楼主就着自己对它们的浅显认识,来粗略地理理以备 ...
- HoloLens开发手记 - Unity之Keyboard input 键盘输入
虽然HoloLens支持很多种输入方式,包括蓝牙键盘在内.但是大部分应用还是不能断定用户有物理键盘可以输入,所以虚拟键盘输入还是必须要提供的. Unity提供了一个TouchScreenKeyboar ...
- 【MPI学习7】MPI并行程序设计模式:MPI的进程组和通信域
基于都志辉老师MPI编程书中的第15章内容. 通信域是MPI的重要概念:MPI的通信在通信域的控制和维护下进行 → 所有MPI通信任务都直接或间接用到通信域这一参数 → 对通信域的重组和划分可以方便实 ...
- 定制类自己的的new_handler
C++中的new操作符首先使用operator new函数来分配空间,然后再在此空间上调用类的构造函数构造对象.当operator new无法分配所需的内存空间时,默认的情况下会抛出一个bad_all ...