问题描述:
给你一些单词,请你判断能否把它们首尾串起来串成一串。
前一个单词的结尾应该与下一个单词的道字母相同。
如
aloha
dog
arachnid
gopher
tiger
rat
可以拼接成:aloha.arachnid.dog.gopher.rat.tiger
2 6 aloha arachnid dog gopher rat tiger 3 oak maple elm
aloha.arachnid.dog.gopher.rat.tiger ***
分析:
要能拼接在一起,说明这列单词能组成欧拉图或半欧拉图
欧拉图:有向图D是欧拉图当且仅当D是强连通的且每个顶点的入读等于出度。
半欧拉图:有向图D是半欧拉图当且仅当D是单向连通的且恰有两个奇度顶点,其中一个顶点的入度比出度大1,另一个顶点的出度不入度大1,而其余顶点的入读等于出度。
for(int i=0; i<26; i++)
{
if(abs(in[i]-out[i])>=2) return -1; //出度与入度相差不能超过1,abs
else if(in[i]-out[i]==1) end++;
else if(in[i]-out[i]==-1) {start++; ans=i;}
}
if(start>1 ||end>1) return -1; //不能有多个头结点和多个尾节点
此外,这样判断下来也并不能说明一定满足欧拉图或半欧拉图,因为可能会出项特殊数据:
例如:"aaa","bbb","ccc","bbb",这几个单词的入度等于出度,但却不能连成欧拉回路
代码:
#include <stdio.h> #include <string.h> #include <algorithm> using namespace std; int m,order[1005],in[30],out[30]; bool used[1005]; struct node { char s[35]; int f,l; }N[1005]; bool cmp(node n1,node n2) { return strcmp(n1.s,n2.s)<0; } int judge() { int start=0,end=0,ans; for(int i=0; i<26; i++) { if(abs(in[i]-out[i])>=2) return -1; //出度与入度相差不能超过1,abs else if(in[i]-out[i]==1) end++; else if(in[i]-out[i]==-1) {start++; ans=i;} } if(start>1 ||end>1) return -1; //不能有多个头结点和多个尾节点 if(start==0) { for(int i=0; i<26; i++) { if(out[i]) return i; //随便返回字典序里的第一个单词位置 } } else return ans; } bool dfs(int x,int cnt) { if(cnt==m) return 1; for(int i=0; i<m; i++) { if(N[i].f<x || used[i]) continue; else if(N[i].f>x) return false; //'aaa','bbb','ccc','ddd',虽出度等于入读,但却不能连成回路 used[i] = true; order[cnt] = i; if(dfs(N[i].l, cnt+1)) return 1; //回溯查找 used[i] = false; } return false; } int main() { int t; scanf("%d", &t); while(t--) { memset(N,0,sizeof(N)); memset(used, 0, sizeof(used)); memset(in, 0, sizeof(in)); memset(out, 0, sizeof(out)); memset(order, 0, sizeof(order)); scanf("%d", &m); getchar(); for(int i=0; i<m; i++) { scanf("%s", N[i].s); int len = strlen(N[i].s); N[i].f = N[i].s[0]-'a'; N[i].l = N[i].s[len-1]-'a'; in[N[i].l]++; out[N[i].f]++; } int jd = judge(); if(jd==-1) { puts("***"); continue;} sort(N,N+m,cmp); if(!dfs(jd,0)) { puts("***"); continue;} printf("%s", N[order[0]].s); for(int i=1; i<m; i++) printf(".%s", N[order[i]].s); puts(""); } return 0; }
题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=99