[USACO12DEC]第一!First!(字典树,拓扑排序)
[USACO12DEC]第一!First!
题目描述
Bessie has been playing with strings again. She found that by
changing the order of the alphabet she could make some strings come before all the others lexicographically (dictionary ordering).
For instance Bessie found that for the strings "omm", "moo", "mom", and "ommnom" she could make "mom" appear first using the standard alphabet and that she could make "omm" appear first using the alphabet
"abcdefghijklonmpqrstuvwxyz". However, Bessie couldn't figure out any way to make "moo" or "ommnom" appear first.
Help Bessie by computing which strings in the input could be
lexicographically first by rearranging the order of the alphabet. To compute if string X is lexicographically before string Y find the index of the first character in which they differ, j. If no such index exists then X is lexicographically before Y if X is shorter than Y. Otherwise X is lexicographically before Y if X[j] occurs earlier in the alphabet than Y[j].
Bessie一直在研究字符串。她发现,通过改变字母表的顺序,她可以按改变后的字母表来排列字符串(字典序大小排列)。
例如,Bessie发现,对于字符串串“omm”,“moo”,“mom”和“ommnom”,她可以使用标准字母表使“mom”排在第一个(即字典序最小),她也可以使用字母表“abcdefghijklonmpqrstuvwxyz”使得“omm”排在第一个。然而,Bessie想不出任何方法(改变字母表顺序)使得“moo”或“ommnom”排在第一个。
接下来让我们通过重新排列字母表的顺序来计算输入中有哪些字符串可以排在第一个(即字典序最小),从而帮助Bessie。
要计算字符串X和字符串Y按照重新排列过的字母表顺序来排列的顺序,先找到它们第一个不同的字母X[i]与Y[i],按重排后的字母表顺序比较,若X[i]比Y[i]先,则X的字典序比Y小,即X排在Y前;若没有不同的字母,则比较X与Y长度,若X比Y短,则X的字典序比Y小,即X排在Y前。
输入输出格式
输入格式:
Line 1: A single line containing N (1 <= N <= 30,000), the number of strings Bessie is playing with.
Lines 2..1+N: Each line contains a non-empty string. The total number of characters in all strings will be no more than 300,000. All characters in input will be lowercase characters 'a' through 'z'. Input will contain no duplicate strings.
第1行:一个数字N(1 <= N <= 30,000),Bessie正在研究的字符串的数量。
第2~N+1行:每行包含一个非空字符串。所有字符串包含的字符总数不会超过300,000。 输入中的所有字符都是小写字母,即a~z。 输入不包含重复的字符串。
输出格式:
Line 1: A single line containing K, the number of strings that could be lexicographically first.
Lines 2..1+K: The (1+i)th line should contain the ith string that could be lexicographically first. Strings should be output in the same order they were given in the input.
第1行:一个数字K,表示按重排后的字母表顺序排列的字符串有多少可以排在第一个数量。
第2~K+1行:第i+1行包含第i个按重排后的字母表顺序排列后可以排在第一个的字符串。字符串应该按照它们在输入中的顺序来输出。
输入输出样例
输入样例#1:
4
omm
moo
mom
ommnom
输出样例#1:
2
omm
mom
说明
The example from the problem statement.
Only "omm" and "mom" can be ordered first.
样例即是题目描述中的例子,只有“omm”和“mom”在各自特定的字典序下可以被排列在第一个。
题解
刚学字典树的时候看到这道题,感觉用广搜每次把其他的连边判一下(我是真的蠢,这样想还把时间复杂度算错了),没想到字典树里同一层中没有相同的节点,直接连边即可。最后用拓扑排序判一下环即可。代码略丑
#include<bits/stdc++.h>
using namespace std;
int n,cnt,ans,trie[300010][27],len[30010];
int head[30],du[30],qwe[30010];bool vis[30][30],in[30],end[300010];
struct node{
int to,next;
}edge[900];
string s[30010];
void add(int x,int y)
{
cnt++;edge[cnt].to=y;edge[cnt].next=head[x];head[x]=cnt;
}
queue<int> q;
bool topu()
{
for(int i=1;i<=26;i++)
{
if(!du[i]) q.push(i),in[i]=1;
}
while(q.size())
{
int u=q.front();q.pop();
for(int i=head[u];i;i=edge[i].next)
{
int v=edge[i].to;if(in[v])continue;
du[v]--;if(!du[v])q.push(v),in[v]=1;
}
}
for(int i=1;i<=26;i++)if(!in[i])return false;return true;
}
void clear()
{
cnt=0;memset(head,0,sizeof(head));memset(in,0,sizeof(in));memset(du,0,sizeof(du));
memset(vis,0,sizeof(vis));
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
cin>>s[i];
len[i]=s[i].length();int now=0;
for(int j=0;j<len[i];j++)
{
if(!trie[now][s[i][j]-'a'+1]) trie[now][s[i][j]-'a'+1]=++cnt;
now=trie[now][s[i][j]-'a'+1];
}
end[now]=1;
}
for(int i=1;i<=n;i++)
{
int now=0;clear();bool flag=0;
for(int j=0;j<len[i];j++)
{
int d=s[i][j]-'a'+1;
for(int k=1;k<=26;k++)
{
if(k==d)continue;
if(trie[now][k]&&vis[k][d]){flag=1;break;}
if(trie[now][k]&&!vis[d][k])
{
add(d,k);du[k]++;vis[d][k]=1;
}
}
if(end[now]||flag){flag=1;break;}now=trie[now][d];
}
if(flag)continue;
if(topu()) ans++,qwe[ans]=i;
}
cout<<ans<<endl;
for(int i=1;i<=ans;i++)cout<<s[qwe[i]]<<endl;
}
[USACO12DEC]第一!First!(字典树,拓扑排序)的更多相关文章
- [USACO12DEC]第一!First! (Trie树,拓扑排序)
题目链接 Solution 感觉比较巧的题啊... 考虑几点: 可以交换无数次字母表,即字母表可以为任意形态. 对于以其他字符串为前缀的字符串,我们可以直接舍去. 因为此时它所包含的前缀的字典序绝对比 ...
- 「Usaco2012 Dec」第一(字典树+拓扑排序)
(我恨字符串) 惯例化简题目:给定n个字符串,可以改变字符的相对大小(在字典序中的大小),问:字符串i是否能成为最小的字符串(字典序) 解题过程: 首先你可以预处理出来26的全排列然后暴力然后你只要用 ...
- Luogu P3065 [USACO12DEC]第一!First!【字典树/拓扑排序】By cellur925
题意:给你许多字符串,你可以改变字母序大小,问有哪些字符串可能成为字典序最小的字符串. 我们考虑把这些字符串都塞到\(trie\)树上.之后检索每一个字符串的时候,我们看和他同一层的地方是否有字符,如 ...
- BZOJ_3012_[Usaco2012 Dec]First!_trie树+拓扑排序
BZOJ_3012_[Usaco2012 Dec]First!_trie树+拓扑排序 题意: 给定n个总长不超过m的互不相同的字符串,现在你可以任意指定字符之间的大小关系.问有多少个串可能成为字典序最 ...
- 洛谷P3065 [USACO12DEC]第一!First!(Trie树+拓扑排序)
P3065 [USACO12DEC]第一!First! 题目链接:https://www.luogu.org/problemnew/show/P3065 题目描述 Bessie一直在研究字符串.她发现 ...
- Trie树|字典树(字符串排序)
有时,我们会碰到对字符串的排序,若采用一些经典的排序算法,则时间复杂度一般为O(n*lgn),但若采用Trie树,则时间复杂度仅为O(n). Trie树又名字典树,从字面意思即可理解,这种树的结构像英 ...
- BZOJ3832[Poi2014]Rally——权值线段树+拓扑排序
题目描述 An annual bicycle rally will soon begin in Byteburg. The bikers of Byteburg are natural long di ...
- BZOJ4383 Pustynia(线段树+拓扑排序)
线段树优化建图暴力拓扑排序即可.对于已确定的数,拓扑排序时dp,每个节点都尽量取最大值,如果仍与已确定值矛盾则无解.叶子连出的边表示大于号,其余边表示大于等于. #include<iostrea ...
- [BZOJ2815][ZJOI2012]灾难 灭绝树+拓扑排序+lca
灾难 [问题描述] 阿米巴是小强的好朋友. 阿米巴和小强在草原上捉蚂蚱.小强突然想,如果蚂蚱被他们捉灭绝了,那 么吃蚂蚱的小鸟就会饿死,而捕食小鸟的猛禽也会跟着灭绝,从而引发一系列的 生态灾难. 学过 ...
- Luogu5284 十二省联考2019字符串问题(后缀树+拓扑排序)
对反串建SAM弄出后缀树,每个b串通过倍增定位其在后缀树上对应的节点,根据其长度将节点拆开.然后每个a串也找到对应的节点,由该节点向表示a串的节点连边,再把所给的边连上跑拓扑排序即可. #includ ...
随机推荐
- Oracle诊断:drop table失败[转]
转: From <http://blog.csdn.net/cyxlxp8411/article/details/7775113> 今天在drop一张表的时候报ORA-00054错误 SQ ...
- 读写锁StampedLock的思想
该类是一个读写锁的改进,它的思想是读写锁中读不仅不阻塞读,同时也不应该阻塞写. 读不阻塞写的实现思路: 在读的时候如果发生了写,则应当重读而不是在读的时候直接阻塞写! 因为在读线程非常多而写线程比较少 ...
- ACM ICPC 2011-2012 Northeastern European Regional Contest(NEERC)G GCD Guessing Game
G: 要你去才Paul的年龄,Paul的年龄在1~n之间,你每猜一个Paul会告诉你,你猜的这个数和他年龄的gcd,问在最坏情况下最少要猜多少次. 题解: 什么是最坏情况,我们直到如果他的年龄是1的话 ...
- m3u8直播测试地址
调试m3u8的时候需要测试地址 找了几个,备用一下 安徽卫视 http://stream2.ahtv.cn/ahws/cd/live.m3u8经济生活 http://stream2.ahtv.cn/j ...
- leetcode-mid-sorting and searching - 56 Merge Intervals
mycode 出现的问题:比如最后一个元素是[1,10],1小于前面所有元素的最小值,10大于前面所有元素的最大值,而我最开始的思路只考虑了相邻 参考: 思路:如果我只考虑相邻,必须先将list排序, ...
- kafka 通信报文格式
1. 序列化一条消息 消息有 key 和 value kafka 提供了基础数据类型的序列化工具,对于业务的自定义类需要自行实现序列化 ProducerRecord 是对象,含 KV 和 header ...
- Win8.1+VS2013+WDK8.1+VirtualBox or VMware 驱动开发环境配置
https://blog.csdn.net/charlessimonyi/article/details/50904956 Win8.1+VS2013+WDK8.1+VirtualBox or VMw ...
- ES快速入门
一.概念 1.ES基础概念 ES是ElasticSearch的缩写.ES是基于Apache Lucene的开源搜索引擎,是一款实时分布式搜索和分析引擎,提供RestfulAPI可以进行可视化的交互.具 ...
- python string_2 内建函数详解
先定义2个字符串变量 #coding:utf-8 s1="http" s2="http://www.cnblogs.com/sub2020/p/7988111.html& ...
- hdu5993/2016icpc青岛L
zz:https://www.cnblogs.com/ytytzzz/p/9674661.html 题意:给一棵树,每次询问删掉两条边,问剩下的三棵树的最大直径点10W,询问10W,询问相互独立 So ...