单词拼接

时间限制:3000 ms  |  内存限制:65535 KB
难度:5

题目链接:点击打开链接

描述

给你一些单词,请你判断能否把它们首尾串起来串成一串。

前一个单词的结尾应该与下一个单词的道字母相同。

aloha

dog

arachnid

gopher

tiger

rat

可以拼接成:aloha.arachnid.dog.gopher.rat.tiger

输入
第一行是一个整数N(0<N<20),表示测试数据的组数
每组测试数据的第一行是一个整数M,表示该组测试数据中有M(2<M<1000)个互不相同的单词,随后的M行,每行是一个长度不超过30的单词,单词全部由小写字母组成。
输出
如果存在拼接方案,请输出所有拼接方案中字典序最小的方案。(两个单词之间输出一个英文句号".")
如果不存在拼接方案,则输出
***
样例输入
2
6
aloha
arachnid
dog
gopher
rat
tiger
3
oak
maple
elm
样例输出
aloha.arachnid.dog.gopher.rat.tiger
***

分析:

本题是可以将单词看成是一条边,而首尾的两个可以看成是两个点,每一条边连接着首尾的两个单词,而根据题中的意思,我们需要找到一条欧拉路,让每条边都走一遍,但是也能存在有环的情况,所以对于每个点的度我们都要有所记录,可以当做判断的条件,因为可以成环,也可以不成环,如果不成环,那么肯定有一个点的出度比入度大一,有一个点的入度比出度大一,在这种情况下,是不是我们就可以找到开始点了,于是再将所有的单词按字典树的顺序排好序,进行 dfs ,如若存在符合题意的序列就可将其下标保存在一个数组中,然后将输出,如果成环的话,那么我们就找字典序排列最小的且有出度的点,再进行 dfs ,如果对 dfs 不是太熟悉,感觉或许有点迷,如果不太了解欧拉路,那就自己百度,其实很简单,不要想得太复杂,比如规定的点的度,我们只需要判断其度是否符合要求即可,实在不行的话,可以手动模拟,但是不要不动手就将过程中的点想的那么复杂,好了,我们来看看代码吧,在代码中需要注意的地方,我会写上详细的注释哦。。

在这里解释代码中注释的不详细的名词:

相同点:点,指的是单词的首和尾,相同的点指的是单词中相同的首字母或尾字母,可能不是出现在同一个单词中,这样统计不会有影响

#include <iostream>
#include<stdio.h>
#include<string>
#include<string.h>
#include<algorithm>
#include<math.h>
using namespace std;struct book{char w[35];///存单词int s,e;///村单词的首字母和尾字母
}h[1005];bool cmp(struct book a,struct book b)///将单词排序
{return strcmp(a.w,b.w)<0;
}int n,m;int outdegree[1005],indegree[1005],vis[1005],pre[1005];int judge()///判断点的出度和入度,看是否符合欧拉回路{int outdegree1=0,indegree1=0,bj=0;for(int i=0;i<26;i++)///将所有点的情况进行统计{if(abs(outdegree[i]-indegree[i])>=2)///此情况说明不符合欧拉回路return -1;else if(outdegree[i]-indegree[i]==1)///此情况很能是起始点,有出度没有入度{outdegree1++;///记录所有点多出的出度bj=i;}else if(outdegree[i]-indegree[i]==-1)///此情况很可能是终点,有入度没有出度indegree1++;///记录所有点多出的入度}if(indegree1>1||outdegree1>1)///此情况说明不符合欧拉路return -1;else if(outdegree-indegree==0)///此情况说明是欧拉回路{for(int i=0;i<26;i++){if(outdegree[i])///则要返回的是字典树最小且有出度的单词,将其作为起点return i;}}elsereturn bj;///如果不成环,就返回起点}int dfs(int k,int num)///找是否有符合题意的排列{if(num==m)///如果等于m,说明我们已经找到符合题意的顺序了return 1;for(int i=0;i<m;i++)///遍历m个单词{if(vis[i]||h[i].s<k)///说明次单词不可用continue;else if(h[i].s>k)///说明已经没有以单词k为首字母的单词可用了,因为我们排过序了     return 0;else if(h[i].s==k)///说明找到可用的单词了{vis[i]=1;///将次单词标记pre[num]=i;///将其下标存着/**接下来的dfs尤为注意,我之前没有将它放进if里判断,然后错了,因为我们本题要找的是序列,如果不判断直接dfs,然后接着就将标记取消的话,可能有些单词我们已经找到它的位置了,回溯的时候将标记都取消的话,意味着我们像找有多少条路径能出迷宫一样,那不适用于本题,本题只需要将找不到以该单词的末尾单词为首元素并且还有没有排序的单词的单词取消标记,再重新调整位置而已,这里要仔细理解**/if(dfs(h[i].e,num+1))return 1;vis[i]=0;}}return 0;}int main()
{scanf("%d",&n);while(n--){scanf("%d",&m);memset(outdegree,0,sizeof(outdegree));///存相同点的出度memset(indegree,0,sizeof(indegree));///存相同点的入度for(int i=0;i<m;i++){scanf("%s",&h[i].w);int len=strlen(h[i].w);h[i].s=h[i].w[0]-'a';///存首字母h[i].e=h[i].w[len-1]-'a';///存尾字母outdegree[h[i].s]++;///对应的出度和入度++indegree[h[i].e]++;}int ok=judge();/**接受judge()函数返回的参数,刚开始我将判断错误的返回0,后来想不对,因为正确的时候返回也有可能是0,因为下标是从0开始的**/if(ok==-1)///说明判断点的出度入度就不符合欧拉图{printf("***\n");continue;}sort(h,h+m,cmp);///将单词进行字典序的顺序排列memset(vis,0,sizeof(vis));///将标记数组初始化if(!dfs(ok,0))///如果不能找到能将所有的单词首尾相接的话{printf("***\n");continue;}for(int i=0;i<m;i++)///按照dfs中pre数组保存的序号输出h.w中对应的单词即可{if(i==0)printf("%s",h[pre[i]].w);elseprintf(".%s",h[pre[i]].w);}printf("\n");}return 0;
}

NYOJ 99-单词拼接相关推荐

  1. NYOJ 99单词拼接(有向图的欧拉(回)路)

    1 /* 2 NYOJ 99单词拼接: 3 思路:欧拉回路或者欧拉路的搜索! 4 注意:是有向图的!不要当成无向图,否则在在搜索之前的判断中因为判断有无导致不必要的搜索,以致TLE! 5 有向图的欧拉 ...

  2. NYOJ 99 单词拼接

    单词拼接 时间限制:3000 ms  |  内存限制:65535 KB 难度:5 描述 给你一些单词,请你判断能否把它们首尾串起来串成一串. 前一个单词的结尾应该与下一个单词的道字母相同. 如 alo ...

  3. NYOJ - 99:单词拼接

    单词拼接 来源:NYOJ 标签:图论,欧拉图,欧拉路径 参考资料: 欧拉图:https://baike.baidu.com/item/%E6%AC%A7%E6%8B%89%E5%9B%BE 相似题目: ...

  4. C语言DFS(7)___单词拼接(NYoj 99)

    单词拼接 描述 给你一些单词,请你判断能否把它们首尾串起来串成一串. 前一个单词的结尾应该与下一个单词的道字母相同. 如 aloha dog arachnid gopher tiger rat 可以拼 ...

  5. NYOJ-99 单词拼接(欧拉+回溯)

    单词拼接 时间限制:3000 ms  |  内存限制:65535 KB 难度:5 描述 给你一些单词,请你判断能否把它们首尾串起来串成一串. 前一个单词的结尾应该与下一个单词的道字母相同. 如 alo ...

  6. 单词拼接 ----- 深搜

    先判断这些单词能不能构成 接龙 , 能的话在排序 , 然后深搜确定接龙 . 题解 : 如果先确定所有单词的首尾字母的个数 , 如果首字母个数等于尾字母个数就不用管了 , 如果发现首字母比尾字母大1那个 ...

  7. NYOJ99 单词拼接

    题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=99 题目分析: 其实上这道题把给的单词转化成一个图,然后考察这个图是否具有一个欧拉回路. ...

  8. 计蒜客习题:单词拼接

    问题描述 花椰菜君给了蒜头君 n 个单词,如果一个单词的最后一个字母和另一个单词的第一个字母相同,那么两个单词就可以连接在一起组成一个新的单词.现在花椰菜君想要蒜头君计算一下,给定的 n 个单词是否可 ...

  9. LeetCode-算法-拼接单词

    力扣题目地址:https://leetcode-cn.com/problems/find-words-that-can-be-formed-by-characters/ 首先看题目: 给你一份『词汇表 ...

最新文章

  1. 数学之美系列十七 -- 谈谈搜索引擎作弊问题(Search Engine Anti-SPAM)
  2. MySQL【环境搭建 01】Linux root 用户部署 mysql-5.7.28 及 not allowed to connect to this MySQL server 和中文乱码问题处理
  3. 华为开发者被批评在 Linux 内核刷 KPI
  4. 800乘600的分辨率_600元能买到啥配置的手机?
  5. Maven多模块,Dubbo分布式服务框架,SpringMVC,前后端分离项目,基础搭建,搭建过程出...
  6. PHP 错误与异常 笔记与总结(6)将错误日志保存在系统日志中
  7. 一年级abb式词语并造句_ABB式词语如何活学活用,家长都收藏了!
  8. 文档02_JavaScript
  9. oracle编码储存过程,oracle存储过程代码实例一
  10. 来瞧瞧这40个效果惊人的单页设计
  11. Java-springboot生鲜电商项目(四)商品模块
  12. 【NOIP2014】解方程【秦九韶】【高精度处理】
  13. 腾讯云直播、生成腾讯推拉流
  14. 使用FFmpeg工具将一个图片和一个音频合成一个视频以及在window系统下使用脚本运行
  15. c#安卓连接sqlserver_C#手把手教你玩微信自动化
  16. Qt Mtd调用方式
  17. 设计模式的六大原则(SOLID)
  18. oracle导入dmp秒退,Oracle导入dmp遇到问题解决
  19. android录制视频实现
  20. 卸载anaconda pytorch

热门文章

  1. 五年级计算机的软件教案,五年级信息技术教案
  2. 项目总结(关于fixed/absolute固定的底部按钮被input输入框的键盘顶上去的问题一般安卓手机会出现这种问题)
  3. HTML+CSS 登录页面
  4. Dev c++ 5.11 调试方法入门 初学者适用
  5. 陶梅霞, 主研方向为物理层网络编码、无线资源分配、MIMO技术及物理层安全
  6. python cx_Oracle 2
  7. 量子计算助力新冠病毒检测
  8. 作业5:SVM实现鸢尾花分类
  9. 不懂讨好领导,不会人情事故,也是种错吗?
  10. R数据分析——安装,数据类型转换,向量