Catenyms
Time Limit : 2000/1000ms (Java/Other) Memory Limit : 131072/65536K (Java/Other)
Total Submission(s) : 6 Accepted Submission(s) : 5
Problem Description
A catenym is a pair of words separated by a period such that the last letter of the first word is the same as the last letter of the second. For example, the following are catenyms:
dog.gopher
gopher.rat
rat.tiger
aloha.aloha
arachnid.dog
A compound catenym is a sequence of three or more words separated by periods such that each adjacent pair of words forms a catenym. For example,
aloha.aloha.arachnid.dog.gopher.rat.tiger
Given a dictionary of lower case words, you are to find a compound catenym that contains each of the words exactly once.
Input
The first line of standard input contains t, the number of test cases. Each test case begins with 3 <= n <= 1000 - the number of words in the dictionary. n distinct dictionary words follow; each word is a string of between 1 and 20 lowercase letters on a line by itself.
Output
For each test case, output a line giving the lexicographically least compound catenym that contains each dictionary word exactly once. Output "***" if there is no solution.
Sample Input
2
6
aloha
arachnid
dog
gopher
rat
tiger
3
oak
maple
elm
Sample Output
aloha.arachnid.dog.gopher.rat.tiger
***
题目大意:输入n个单词,每个单词都形成一条从该单词首字母到尾字母的边,单词尾字母要与下一个单词首字母相同,若可以组成这样的路,即可以组成这样一条连着的单词串,输出路径(单词串),若有多条,则要按字典顺序输出,找不到路则输出***。
此题搞了很长的时间啊,主要是建边那一部分,看了很久,不能用邻接矩阵,后来就用了链表,还有输出路径这个难搞啊,后来参考了一下别人的代码,发现那个dfs路径竟然如此巧妙!实在很巧妙!
代码:
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <cstring>
#include <string>
#include <algorithm>
#include <math.h>
using namespace std;
bool app[30];
char res[1005][26];
int in[30], out[30], deg[30], father[30], adj[30];
int n, ant, odd, begin, end;
struct edge
{
bool vis;
char sh[25];
int y, next;
}a[1005];
bool cmp(edge a, edge b)
{
return strcmp(a.sh, b.sh) > 0;
}
void init()
{
int i;
ant = odd = 0;
memset(app, false, sizeof(app));
memset(in, 0, sizeof(in));
memset(out, 0, sizeof(out));
memset(deg, 0, sizeof(deg));
memset(adj, -1, sizeof(adj));
for(i = 0; i < 1005; i++) a[i].vis = false;
for(i = 0; i < 26; i++) father[i] = i;
}
int find(int x)
{
if(x != father[x])
{
father[x] = find(father[x]);
}
return father[x];
}
void Union(int x, int y)
{
father[x] = y;
}
int judge() //判断是否满足欧拉。0不满足,1欧拉回路,2欧拉路
{
int i, k;
for(i = 0; i < 26; i++) //判断有向图欧拉
{
if(!app[i]) continue;
deg[i] = in[i] - out[i];
if(abs(deg[i]) > 1) return 0;
if(deg[i] > 0) begin = i; //起点
if(deg[i] < 0) end = i; //终点
if(deg[i]%2) odd++;
if(odd > 2) return 0;
}
for(i = 0; i < 26; i++) if(app[i]) break;
k = find(i);
for(i = k+1; i < 26; i++) //判断连通性
{
if(!app[i]) continue;
if(k != find(i)) return 0;
}
if(odd == 0) //有欧拉回路
{
for(i = 0; i < 26; i++)
if(app[i]) break;
begin = i;
return 1;
}
return 2;
}
void dfs(int x, int id) //深搜寻找欧拉路径,很巧妙!!!
{
int i;
for(i = adj[x]; i != -1; i = a[i].next)
{
if(!a[i].vis)
{
a[i].vis = true;
dfs(a[i].y, i);
}
}
if(id != -1) strcpy(res[ant++], a[id].sh); //最先进去的肯定是终点
}
int main()
{
int i, x, y, fx, fy, t, len, tar;
scanf("%d", &t);
while(t--)
{
init();
scanf("%d", &n);
for(i = 0; i < n; i++)
{
scanf("%s", a[i].sh);
}
//题目要求是字典顺序,但是我是用前插链表,这时的顺序恰好会相反
sort(a, a+n, cmp); //所以排序时从大到小,这样刚刚会是字典顺序
for(i = 0; i < n; i++)
{
len = strlen(a[i].sh);
x = a[i].sh[0] - 'a';
y = a[i].sh[len-1] - 'a';
in[x]++;
out[y]++;
app[x] = true;
app[y] = true;
/// *****建边*****
a[i].y = y;
a[i].next = adj[x];
adj[x] = i;
/// ***************
fx = find(x);
fy = find(y);
if(fx != fy) Union(fx, fy);
}
tar = judge();
if(tar == 0)
{
printf("***\n");
continue;
}
dfs(begin, -1);
printf("%s", res[ant-1]);
for(i = ant-2; i >= 0; i--)
{
printf(".%s", res[i]);
}
printf("\n");
}
return 0;
}
分享到:
相关推荐
题目"POJ-2870 Light Up"是一个经典的图论问题,主要涉及深度优先搜索(DFS)算法的运用。该问题要求点亮一个矩形区域内的所有障碍物,每个障碍物需要特定数量的灯光才能被照亮,且相邻的障碍物之间不能有空格。题目...
根据给定的信息,本文将详细解释“POJ 1988 简单并查集”中的核心知识点,包括并查集的基本概念、代码实现以及在本题中的具体应用。 ### 并查集基本概念 并查集是一种用于处理一些不交集的合并及查询问题的数据...
【标题】"POJ1691-Painting A Board 【拓扑+DFS】"是一个源自北京大学在线编程平台POJ的编程题目,它主要涉及到图论中的拓扑排序和深度优先搜索(DFS)算法。该题目的核心是解决一个与涂色相关的实际问题,通过运用...
poj2492 A Bug's Life并查集应用的扩展,希望可以给大家带来用处
总的来说,解答POJ3009-Curling 2.0问题需要对DFS、向量、回溯和剪枝有深入的理解,并能灵活运用到具体问题中。通过对这些技术的熟练掌握,不仅可以解决这道题目,还能够为其他类似问题提供有效的解决方案。
【标题】"POJ3733-Changing Digits【DFS+强剪枝】"是一个来自北京大学在线评测系统POJ的编程题目,该题目主要涉及深度优先搜索(DFS)算法和强剪枝策略。在算法竞赛和编程挑战中,这类问题通常要求参赛者通过编写...
标题“POJ3373-Changing Digits【DFS+强剪枝】”涉及的是一个编程竞赛中的问题,这个问题在北大POJ(北京大学在线评测系统)平台上被提出。"Changing Digits"是一个算法挑战,而解决方案是通过深度优先搜索(DFS)...
对于没有父节点指针的普通二叉树,解决LCA的方法通常涉及到深度优先搜索(DFS)。我们可以从根节点开始,找到给定节点的路径,并存储在向量中。例如,假设我们有以下二叉树: ``` 10 / \ 6 14 / \ / \ 4 8 12 16 ...
- **题目描述**:构建特定类型的图——德布鲁因图,并找出其欧拉回路。 - **解题思路**:构建德布鲁因图后,判断其是否存在欧拉回路。 - **数据结构**:邻接表。 5. **【HDU】1956 Sightseeing tour 混合欧拉** ...
此外,它也是算法竞赛中的常见题目类型,例如POJ等在线编程平台上的题目就经常涉及并查集的使用。 综上所述,并查集是一种非常实用的数据结构,它在处理集合的连接与查找问题时具有高效性和灵活性,对于理解和掌握...
在给出的文件列表中,“POJ1014-Dividing【多重背包+二进制优化】.cpp”和“POJ1014-Dividing【DFS】.cpp”很可能是两份不同的C++代码实现,分别展示了如何结合多重背包和二进制优化以及如何利用DFS来解决问题。...
1. poj2524.cpp:这是一个POJ(Problem Setter's Online Judge)的编程题目,通常涉及到特定的算法问题,可能需要利用并查集解决连通性或路径查找问题。 2. hdoj1233最小生成树,克鲁斯卡尔.cpp:最小生成树是图论...
* 简单并查集的应用 * 哈希表和二分查找等高效查找法 + poj3349, poj3274, poj2151, poj1840, poj2002, poj2503 * 哈夫曼树:poj3253 * 堆 * Trie树:静态建树、动态建树 + poj2513 四、简单搜索 * 深度优先搜索...
"西北工业大学POJ试题C++答案代码+课程设计"这一标题表明了资源的主要内容,涉及两个核心部分:一是西北工业大学的编程竞赛(POJ,Problem Oriented Judge System)的C++解题代码,二是与这些题目相关的课程设计。...
在给定的标题“1089_bingchaji.rar_1089_bingchaji.rar _并查集”和描述“POJ1089 并查集可以解决 并查集加路径压缩”中,我们可以看到这是一个关于使用并查集解决特定问题的案例,可能来自于编程竞赛或练习。...
【标题】"POJ1020-Anniversary Cake【有技巧的DFS】"是一个源自北京大学在线编程平台POJ的编程题目,它涉及到深度优先搜索(DFS)算法的应用。这道题目要求参赛者通过编程解决一个有趣的问题,即在特定条件下如何...
这份代码用C++实现了经典算法并查集,来源于poj题目1182
《POJ1207-The 3n + 1 problem》是北京大学在线编程平台POJ上的一道经典算法题目,其主要涉及的知识点是数论和动态规划。本题目的核心是解决著名的“Collatz Conjecture”问题,也被称为“3n+1猜想”。 3n+1猜想是...
并查集基础 acm 算法 poj oi 并查集基础.ppt
一种常见的方法是使用深度优先搜索(DFS)或广度优先搜索(BFS)来构建线段之间的连接,并通过并查集(Disjoint Set)数据结构来判断是否存在不相交的集合。 1. **数据结构**:首先,我们需要用数组或者链表存储...