[Luogu3065][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个按重排后的字母表顺序排列后可以排在第一个的字符串。字符串应该按照它们在输入中的顺序来输出。
输入输出样例
4
omm
moo
mom
ommnom
2
omm
mom
说明
The example from the problem statement.
Only "omm" and "mom" can be ordered first.
样例即是题目描述中的例子,只有“omm”和“mom”在各自特定的字典序下可以被排列在第一个。
其实题目意思还是很清晰易懂的。
一周之前就想写了这题,无奈一直考试(爆零无数)。
我们要通过修改字典序来使得某一个串的字典序最小。
我们考虑这样一个问题如果串$x$与其他的串的$l$前面的位置都一样,那么我们一定要让$l$位置的字符的字典序排在其他的前面。
这个明显的关系可以用拓扑排序。
所以对所有串建$trie$树,我们枚举一个串可以成为答案,然后把不匹配的字符连边,跑拓扑判断是否有环。
#include <bits/stdc++.h>
using namespace std;
#define reg register
int n, ans;
char str[][];
bool can[], cant[];
bool appear[][];
int nxt[][], tot, dep[], End[];
inline void Insert(char *s)
{
int len = strlen(s + );
int now = ;
for (reg int i = ; i <= len ; i ++)
{
if (!nxt[now][s[i]-'a']) nxt[now][s[i]-'a'] = ++tot, dep[nxt[now][s[i]-'a']] = dep[now] + ;
now = nxt[now][s[i]-'a'];
appear[dep[now]][s[i]-'a'] = ;
}
End[now] = ;
} void dfs(int x, bool ap)
{
if (ap) cant[x] = ;
for (reg int i = ; i <= ; i ++)
if (nxt[x][i]) dfs(nxt[x][i], ap | End[x]);
} vector <int> ve[];
int deg[];
bool ex[][]; inline bool Topsort()
{
queue <int> q;
for (reg int i = ; i <= ; i ++) if (!deg[i]) q.push(i);
while(!q.empty())
{
int x = q.front();q.pop();
for (reg int i = ; i < ve[x].size() ; i ++)
{
int to = ve[x][i];
deg[to]--;
if (!deg[to]) q.push(to);
}
}
for (reg int i = ; i <= ; i ++)
if (deg[i]) return ;
return ;
} inline bool Build(int id)
{
for (reg int i = ; i <= ; i ++) ve[i].clear(), deg[i] = ;
int len = strlen(str[id] + );
int now = ;
for (reg int i = ; i <= len ; i ++)
{
for (reg int j = 'a' ; j <= 'z' ; j ++)
{
if (!nxt[now][j-'a'] or j == str[id][i]) continue;
ve[j-'a'].push_back(str[id][i]-'a');
deg[str[id][i]-'a']++;
// printf("%c -> %c\n", j, str[id][i]);
}
now = nxt[now][str[id][i]-'a'];
if (cant[now]) return ;
}
return Topsort();
} int main()
{
scanf("%d", &n);
for (reg int i = ; i <= n ; i ++)
{
scanf("%s", str[i] + );
Insert(str[i]);
}
dfs(, );
for (reg int i = ; i <= n ; i ++)
{
can[i] = Build(i);
ans += can[i];
// printf("%d %d\n", i, can[i]);
}
cout << ans << endl;
for (reg int i = ; i <= n ; i ++)
if (can[i]) {
int len = strlen(str[i] + );
for (reg int j = ; j <= len ; j ++) printf("%c", str[i][j]);
puts("");
}
return ;
}
[Luogu3065][USACO12DEC]第一!First!的更多相关文章
- [bzoj3012][luogu3065][USACO12DEC][第一!First!] (trie+拓扑排序判环)
题目描述 Bessie has been playing with strings again. She found that by changing the order of the alphabe ...
- [luogu P3065] [USACO12DEC]第一!First!
[luogu P3065] [USACO12DEC]第一!First! 题目描述 Bessie has been playing with strings again. She found that ...
- 洛谷P3065 [USACO12DEC]第一!First!(Trie树+拓扑排序)
P3065 [USACO12DEC]第一!First! 题目链接:https://www.luogu.org/problemnew/show/P3065 题目描述 Bessie一直在研究字符串.她发现 ...
- [USACO12DEC]第一!First! (Trie树,拓扑排序)
题目链接 Solution 感觉比较巧的题啊... 考虑几点: 可以交换无数次字母表,即字母表可以为任意形态. 对于以其他字符串为前缀的字符串,我们可以直接舍去. 因为此时它所包含的前缀的字典序绝对比 ...
- [USACO12DEC]第一!First!(字典树,拓扑排序)
[USACO12DEC]第一!First! 题目描述 Bessie has been playing with strings again. She found that by changing th ...
- 【[USACO12DEC]第一!First!】
一个串不能成为第一的情况有两种 另外一个单词是它的前缀 在分配字母表大小关系的时候出现了矛盾的情况 第一种很好判断,一旦我们在一个单词没有匹配完之前遇到一个结束标志,那么就说明另外一个单词是它的前缀 ...
- P3065 [USACO12DEC]第一!First!
题目描述 Bessie has been playing with strings again. She found that by changing the order of the alphabe ...
- Luogu P3065 [USACO12DEC]第一!First!【字典树/拓扑排序】By cellur925
题意:给你许多字符串,你可以改变字母序大小,问有哪些字符串可能成为字典序最小的字符串. 我们考虑把这些字符串都塞到\(trie\)树上.之后检索每一个字符串的时候,我们看和他同一层的地方是否有字符,如 ...
- 菜鸟Python学习笔记第一天:关于一些函数库的使用
2017年1月3日 星期二 大一学习一门新的计算机语言真的很难,有时候连函数拼写出错查错都能查半天,没办法,谁让我英语太渣. 关于计算机语言的学习我想还是从C语言学习开始为好,Python有很多语言的 ...
随机推荐
- Java,Python,前端,Linux,公众号等5T编程资源整理免费下载
场景 我的CSDN: https://blog.csdn.net/BADAO_LIUMANG_QIZHI 实现 马士兵Java学习视频 方立勋JavaWeb 尚硅谷Python核心基础 数据分析 机器 ...
- Servlet实现用户登录
1.登录过程分析: 通过表单收集用户的数据,Servlet通过request对象获得用户提交的数据,服务器还需要从数据库中通过sql语句查询有没有表单提交的数据中的用户.有则登录成功,否则,登录失败. ...
- Elastic Stack 笔记(四)Elasticsearch5.6 索引及文档管理
博客地址:http://www.moonxy.com 一.前言 在 Elasticsearch 中,对文档进行索引等操作时,既可以通过 RESTful 接口进行操作,也可以通过 Java 也可以通过 ...
- SqlServer 统计1-12月份 每个月的数据(临时表)
想做一个年度图表 效果如下,通过sqlserver来统计今年1-12月份每个月的数据,效果如下 sql语句网上找了很多都没有找到满意的 找到的其中一种写法是这样子的 这种写法对于前端来说很方便 不用进 ...
- (二)spring 高级装配-Condition -条件化的bean
Condition:满足某个特定条件的情况下创建bean 条件化配置bean: a:@Conditional 指定一个class ,它指明了通过条件对比的类.如果没有指定class则通过Condito ...
- 0x7fffffff的意思
7fffffff是8位16进制 每个16进制代表4个bit 8✖4bit=32bit=4Byte f的二进制为:1111,7的二进制位0111 int类型的长度位4Byte 左边起,第一位为符号位,0 ...
- Containers vs Serverless:你选择谁,何时选择?
两者都是当今技术时代的热门话题,也都被视为是开发技术的竞争对手. 首先,还有相当多的好奇和担心.此外,两者都是可供工程师使用的.高效的.机器无关的抽象. 但是,在冠军之间,有一个不可逾越的鸿沟.你要么 ...
- java数据结构——递归(Recursion)例题持续更新中
继续学习数据结构递归,什么是递归呢?字面理解就是先递出去,然后回归,递归核心思想就是直接或间接调用本身,好比从前有座山,山里有位老和尚,在给小和尚讲故事,讲的是从前有座山,山里有位老和尚,在给小和尚讲 ...
- FPGA 内部详细架构你明白了吗?
FPGA 芯片整体架构如下所示,大体按照时钟域划分的,即根据不同的工艺.器件速度和对应的时钟进行划分: FPGA 内部详细架构又细分为如下六大模块: 1.可编程输入输出单元(IOB)(Input Ou ...
- python语言程序设计基础 习题 天天向上的力量(math.pow)
实例1: 一年365天,,以第一天的能力值为基数1.0,当好好学习时能力值相比前一天提高1%,没有学习时能力值相比前天要降低1%,每天努力和每天放任,一年下来的能力值相差多少? 解析: 如果每天都好好 ...