POJ - 2337 Catenyms(单词拼接)欧拉通路
2016-07-21 17:54
337 查看
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:
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
Sample Output
分析:
欧拉路径和欧拉回路
欧拉路径:从某结点出发一笔画成所经过的路线叫做欧拉路径。
欧拉回路:在欧拉路径的基础上又回到起点。
a、凡是由偶点组成的连通图,一定可以一笔画成。画时可以把任一偶点为起点,最后一定能以这个点为
终点画完此图。
b、凡是只有两个奇点的连通图(其余都为偶点),一定可以一笔画成。画时必须把一个奇点为起点,另
一个奇点终点。
c、其他情况的图都不能一笔画出。(有偶数个奇点除以2便可算出此图需几笔画成。)
欧拉回路和欧拉路径的判断
欧拉回路:
无向图:每个顶点的度数都是偶数,则存在欧拉回路。
有向图:每个顶点的入度都等于出度,则存在欧拉回路。
欧拉路径:
无向图:当且仅当该图所有顶点的度数为偶数 或者 除了两个度数为奇数外其余的全是偶数。
有向图:当且仅当该图所有顶点 出度=入度 或者 一个顶点 出度=入度+1,另一个顶点 入度=出度+1,其他顶点 出度=入度。
#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;
struct node
{
char s[30];
int start,end;
} a[1001];
int f[1001];
int cmp(node p,node q)
{
return strcmp(p.s,q.s)<0;
}
int in[1001],out[1001],order[1001],m;
int fun()
{
int x1,x2,ans=0,i;
x1=x2=0;
for(i=0; i<26; i++)
{
if(abs(in[i]-out[i])>=2)
return -1;
else if((in[i]-out[i])==1)//统计入度大于出度的顶点个数
x1++;
else if(in[i]-out[i]==-1)//统计出度大于入度的顶点个数
{
x2++;
ans=i;//环路的起点
}
}
if(x1>1||x2>1)
return -1;
else if(x1==0)
{
for(i=0; i<26; i++)
if(out[i])
return i;
}
else
return ans;
}
int dfs(int st,int cnt)//深搜判断是否连通
{
int i;
if(cnt==m)
return 1;
for(i=0; i<m; i++)
{
if(a[i].start<st||f[i])
continue;
else if(a[i].start>st)
return 0;
f[i]=1;
order[cnt]=i;
if(dfs(a[i].end,cnt+1))
return 1;
f[i]=0;
}
return 0;
}
int main()
{
int n,slen,i,t;
scanf("%d",&n);
while(n--)
{
memset(f,0,sizeof(f));
memset(in,0,sizeof(in));
memset(out,0,sizeof(out));
scanf("%d",&m);
for(i=0; i<m; i++)
{
scanf("%s",a[i].s);
slen=strlen(a[i].s);
a[i].start=a[i].s[0]-'a';
a[i].end=a[i].s[slen-1]-'a';
in[a[i].end]++;//尾字符作为入度
out[a[i].start]++;//首字母作为出度
}
t=fun();//判断是否能形成欧拉路径
sort(a,a+m,cmp);
if(t==-1||!dfs(t,0))
{
printf("***\n");
continue;
}
printf("%s",a[order[0]].s);
for(i=1; i<m; i++)
printf(".%s",a[order[i]].s);
printf("\n");
}
return 0;
}
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 ***
分析:
欧拉路径和欧拉回路
欧拉路径:从某结点出发一笔画成所经过的路线叫做欧拉路径。
欧拉回路:在欧拉路径的基础上又回到起点。
a、凡是由偶点组成的连通图,一定可以一笔画成。画时可以把任一偶点为起点,最后一定能以这个点为
终点画完此图。
b、凡是只有两个奇点的连通图(其余都为偶点),一定可以一笔画成。画时必须把一个奇点为起点,另
一个奇点终点。
c、其他情况的图都不能一笔画出。(有偶数个奇点除以2便可算出此图需几笔画成。)
欧拉回路和欧拉路径的判断
欧拉回路:
无向图:每个顶点的度数都是偶数,则存在欧拉回路。
有向图:每个顶点的入度都等于出度,则存在欧拉回路。
欧拉路径:
无向图:当且仅当该图所有顶点的度数为偶数 或者 除了两个度数为奇数外其余的全是偶数。
有向图:当且仅当该图所有顶点 出度=入度 或者 一个顶点 出度=入度+1,另一个顶点 入度=出度+1,其他顶点 出度=入度。
#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;
struct node
{
char s[30];
int start,end;
} a[1001];
int f[1001];
int cmp(node p,node q)
{
return strcmp(p.s,q.s)<0;
}
int in[1001],out[1001],order[1001],m;
int fun()
{
int x1,x2,ans=0,i;
x1=x2=0;
for(i=0; i<26; i++)
{
if(abs(in[i]-out[i])>=2)
return -1;
else if((in[i]-out[i])==1)//统计入度大于出度的顶点个数
x1++;
else if(in[i]-out[i]==-1)//统计出度大于入度的顶点个数
{
x2++;
ans=i;//环路的起点
}
}
if(x1>1||x2>1)
return -1;
else if(x1==0)
{
for(i=0; i<26; i++)
if(out[i])
return i;
}
else
return ans;
}
int dfs(int st,int cnt)//深搜判断是否连通
{
int i;
if(cnt==m)
return 1;
for(i=0; i<m; i++)
{
if(a[i].start<st||f[i])
continue;
else if(a[i].start>st)
return 0;
f[i]=1;
order[cnt]=i;
if(dfs(a[i].end,cnt+1))
return 1;
f[i]=0;
}
return 0;
}
int main()
{
int n,slen,i,t;
scanf("%d",&n);
while(n--)
{
memset(f,0,sizeof(f));
memset(in,0,sizeof(in));
memset(out,0,sizeof(out));
scanf("%d",&m);
for(i=0; i<m; i++)
{
scanf("%s",a[i].s);
slen=strlen(a[i].s);
a[i].start=a[i].s[0]-'a';
a[i].end=a[i].s[slen-1]-'a';
in[a[i].end]++;//尾字符作为入度
out[a[i].start]++;//首字母作为出度
}
t=fun();//判断是否能形成欧拉路径
sort(a,a+m,cmp);
if(t==-1||!dfs(t,0))
{
printf("***\n");
continue;
}
printf("%s",a[order[0]].s);
for(i=1; i<m; i++)
printf(".%s",a[order[i]].s);
printf("\n");
}
return 0;
}
相关文章推荐
- 编程人员的最终追求
- IOS生成同时支持armv7,armv7s,i386的静态库.a文件
- 高质量C和C++编程 读书笔记 (第一二章)
- Android 开发神器系列(工具篇)之 Android WiFi ADB
- Oracle10g安装图解(win7)
- 源码阅读系列:源码阅读方法
- Java 正则表达式
- HTTP报文结构图解
- uva10073 潜水比赛
- C/C++面试题:static(静态)变量的作用
- Zigbee协议栈OSAL层API函数【转载】
- swift - UIProgressView的用法
- JVM 之 GC日志分析
- 神奇的国际日期变更线
- Android第一周(第三部分)
- 通过jquery validate和bootstrap实现表单后面提示打钩或打叉的效果和真实的表单验证
- 三种局域网扫描工具比较
- android之自定义viewGroup仿scrollView详解
- C语言求矩阵偶数的平均值和程序输出某数的问题
- 三种局域网扫描工具比较