Problem 洛谷P1127-词链

Accept: 256    Submit: 1.3k
Time Limit: 1000 mSec    Memory Limit : 128MB

Problem Description

如果单词 XXX 的末字母与单词 YYY 的首字母相同,则 XXX 与 YYY 可以相连成 X.YX.YX.Y 。(注意: XXX 、 YYY 之间是英文的句号“.”)。例如,单词dog与单词gopher,则doggopher可以相连成dog.gopher

另外还有一些例子:

dog.gopher

gopher.rat

rat.tiger

aloha.aloha

arachnid.dog

连接成的词可以与其他单词相连,组成更长的词链,例如:

aloha.arachnid.dog.gopher.rat.tiger

注意到,“.”两边的字母一定是相同的。

现在给你一些单词,请你找到字典序最小的词链,使得这些单词在词链中出现且仅出现一次。

 Input

第一行是一个正整数 n(1≤n≤1000),代表单词数量。

接下来共有 n行,每行是一个由 1到 20 个小写字母组成的单词

 Output

只有一行,表示组成字典序最小的词链,若不存在则只输出三个星号“ ∗∗∗”

 

 Sample Input

6
aloha
arachnid
dog
gopher
rat
tiger

 Sample Output

aloha.arachnid.dog.gopher.rat.tiger
 
题目链接:https://www.luogu.org/problemnew/show/P1127
 
这个题做的很差,感觉很简单,可能还是学艺不精。
 
剪枝的方式还是值得一提的,这个题乍一看上去没有剪枝的思路,当把整个链和欧拉路径联系起来思路自然就出来了。
统计每个字符串首尾字母出现次数,在首位出现就++,在末位就--,如果能够连成词链,那么每个字母的统计值只能位0或1,并且如果有1只能是同时有两个,
据此可以作为充要条件判断是否有解。与此同时,一个剪枝的方式也就出来了,如果是一个+1,一个-1的情况,那么+1的那个必定时开头,避免了很多无用的搜索。
字典序的问题还是非常简单的,先按字典序sort一下,链式前向星存图,因此加边的时候倒着来就好,遇到词链就输出,退出程序。
 
还有一个神奇的地方,就是abc和abcb的情况,虽然abc < abcb,但是如果有一个c、b 接上去就成了abcc...、abcbb...
好像用上述算法还是有问题的,原来还听老师讲过一个类似的题,也是这种情况下有点问题,不过都能AC...
 
 
 #include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <string>
#include <stack>
#include <algorithm>
using namespace std; const int maxn = +;
const int maxm = maxn*maxn; int n,tot,head[maxn];
int len[maxn];
bool vis[maxn];
string str[maxn]; struct Edge{
int to,next;
Edge(int to = ,int next = ) : to(to),next(next) {}
}edge[maxm<<]; void AddEdge(int u,int v){
edge[tot].to = v;
edge[tot].next = head[u];
head[u] = tot++;
} int top,sta[maxn<<]; void output(){
cout << str[sta[]];
for(int i = ;i <= n;i++){
printf(".");
cout << str[sta[i]];
}
cout << endl;
exit();
} void dfs(int u){
vis[u] = true;
sta[++top] = u;
for(int i = head[u];i != -;i = edge[i].next){
int v = edge[i].to;
if(!vis[v]) dfs(v);
}
if(top == n) output();
vis[u] = false;
top--;
} const int kind = ;
int con[maxn]; int main()
{
//freopen("input.txt","r",stdin);
cin >> n;
for(int i = ;i <= n;i++){
cin >> str[i];
}
sort(str+,str++n);
top = ;
memset(head,-,sizeof(head));
memset(vis,false,sizeof(vis));
memset(con,,sizeof(con));
for(int i = ;i <= n;i++){
len[i] = str[i].size();
}
for(int i = ;i <= n;i++){
for(int j = n;j >= ;j--){
if(i!=j && str[i][len[i]-] == str[j][]){
AddEdge(i,j);
}
}
}
for(int i = ;i <= n;i++){
con[str[i][]-'a']++;
con[str[i][len[i]-]-'a']--;
}
int head = -,cnt = ,_cnt = ;
for(int i = ;i < kind;i++){
if(con[i] == ){
head = i;
cnt++;
}
else if(con[i] == -){
_cnt++;
}
}
if(cnt== && _cnt==){
for(int i = ;i <= n;i++){
dfs(i);
}
}
else if(cnt== && _cnt==){
for(int i = ;i <= n;i++){
if(str[i][]-'a' == head) dfs(i);
}
}
printf("***\n");
return ;
}
 

洛谷P1127-词链的更多相关文章

  1. P1127 词链

    P1127 词链 题目描述 如果单词X的末字母与单词Y的首字母相同,则X与Y可以相连成X.Y.(注意:X.Y之间是英文的句号“.”).例如,单词dog与单词gopher,则dog与gopher可以相连 ...

  2. 【算法学习】【洛谷】树链剖分 & P3384 【模板】树链剖分 P2146 软件包管理器

    刚学的好玩算法,AC2题,非常开心. 其实很早就有教过,以前以为很难就没有学,现在发现其实很简单也很有用. 更重要的是我很好调试,两题都是几乎一遍过的. 介绍树链剖分前,先确保已经学会以下基本技巧: ...

  3. 洛谷P3384 树链剖分

    如题,已知一棵包含N个结点的树(连通且无环),每个节点上包含一个数值,需要支持以下操作: 操作1: 格式: 1 x y z 表示将树从x到y结点最短路径上所有节点的值都加上z 操作2: 格式: 2 x ...

  4. 洛谷 P3384 树链剖分(模板题)

    题目描述 如题,已知一棵包含N个结点的树(连通且无环),每个节点上包含一个数值,需要支持以下操作: 操作1: 格式: 1 x y z 表示将树从x到y结点最短路径上所有节点的值都加上z 操作2: 格式 ...

  5. 【树链剖分】洛谷P3379 树链剖分求LCA

    题目描述 如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 输入输出格式 输入格式: 第一行包含三个正整数N.M.S,分别表示树的结点个数.询问的个数和树根结点的序号. 接下来N-1行每 ...

  6. 洛谷 4115 Qtree4——链分治

    题目:https://www.luogu.org/problemnew/show/P4115 论文:https://wenku.baidu.com/view/1bc2e4ea172ded630b1cb ...

  7. 洛谷P2146 树链剖分

    题意 思路:直接树链剖分,用线段树维护即可,算是树剖的经典题目吧. 代码: #include <bits/stdc++.h> #define ls(x) (x << 1) #d ...

  8. 洛谷 [P3384] 树链剖分 模版

    支持各种数据结构上树,注意取膜. #include <iostream> #include <cstring> #include <algorithm> #incl ...

  9. 洛谷 P3384树链剖分 题解

    题面 挺好的一道树剖模板: 首先要学会最模板的树剖: 然后这道题要注意几个细节: 初始化时,seg[0]=1,seg[root]=1,top[root]=root,rev[1]=root; 在线段树上 ...

  10. 树链剖分详解(洛谷模板 P3384)

    洛谷·[模板]树链剖分 写在前面 首先,在学树链剖分之前最好先把 LCA.树形DP.DFS序 这三个知识点学了 emm还有必备的 链式前向星.线段树 也要先学了. 如果这三个知识点没掌握好的话,树链剖 ...

随机推荐

  1. SpringBoot+kafka+ELK分布式日志收集

    一.背景 随着业务复杂度的提升以及微服务的兴起,传统单一项目会被按照业务规则进行垂直拆分,另外为了防止单点故障我们也会将重要的服务模块进行集群部署,通过负载均衡进行服务的调用.那么随着节点的增多,各个 ...

  2. 点到圆弧的距离(csu1503)+几何

    1503: 点到圆弧的距离 Time Limit: 1 Sec  Memory Limit: 128 MB  Special JudgeSubmit: 325  Solved: 70[Submit][ ...

  3. 协程与Epoll的配合

    想快速了解协程与网络调用的原来么,那么请赶紧关闭本页,因为下面都是在扯淡. 这几天是端午假期,第一天大算照着网上一大堆基于ucontext来写协程的文章自己也写一个简单的协程实现.于是第一天我就开始动 ...

  4. C#导入Excel、Excel导入、导入.xls 、导入.xlsx、Excel2003版本、Excel2007版本

    C#导入Excel: 1.选择Excel 03版文件 2.选择需要读取数据的Excel工作表   3.选择工作表中需要读取的列 源码地址在图片下面,不要点击图片,点击下载地址跳转下载.

  5. module.js:549 throw err;

    解决方法: 1.有可能是拼写错误 2.未明原因. (1)删除 node_modules 文件夹 (2)cnpm cache clean,不过提示错误就用 cnpm cache clean --forc ...

  6. 中国最强AI超级服务器问世,每秒提供AI计算2000万亿次

    https://mp.weixin.qq.com/s/1EVczHp11OJ4GEjeE3z5cA 业内唯一以“AI计算”为核心的人工智能大会昨天发布了一份重要报告. 9月12日,<中国AI计算 ...

  7. Tars 负载均衡

    // 传入主控地址,在 db_tars t_registry_info 表中 Communicator communicator = CommunicatorFactory.getInstance() ...

  8. 矢量图面层和线层相交得到相交后的线层文件(gis相交)

    目的:将arcgis里的面层和线层相交(重叠)部分的线单独生成一个shp文件,用于道路路网密度计算等. 注意:进行相交运算后生成的是线要素文件,相当于把面线相交部分的线单独拿了出来. 操作例子:将图示 ...

  9. iOS 10.3下解决Fiddler代理抓包ssl证书信任问题

    iPhone系统更新到iOS 10.3以后,设置fiddler代理抓包,会出现无法抓取https请求,app请求失败的问题 这是因为在iOS 10.3之前,当你将安装fiddler的自定义证书后,iO ...

  10. mysql之用户管理

    本文内容: 用户的介绍 查看用户 创建用户帐户 修改账户 删除帐户 关于匿名用户 首发日期:2018-04-19 用户的介绍: mysql的客户端连接是以用户名来登录服务端. 服务端可以对用户的权限来 ...