P3065 [USACO12DEC]First! G
题意描述
不错的一道题。
给你 \(N\) 个字符串,要求你求出可能的字典序最小的字符串。
对于 可能的最小的字符串,你可以任意排列 \(26\) 个字母,使得其字典序最小。
举个栗子:(好像就是样例)
4
omm
moo
mom
ommnom
首先明确一点:当一个单词为另一个单词的前缀时,较长的单词不可能为字典序最小的。
然后发现:
- 我们可以使用标准字母表使
mom排在第一个。(即字典序最小) - 也可以使用字母表
abcdefghijklonmpqrstuvwxyz使得omm排在第一个。
就是酱紫。
算法分析
字符串让人联想到 \(trie\) 树,优先级关系让人联想到 拓扑排序,于是就解决了。
- 建立一颗 \(trie\) 树。(有需要的可以看看 trie 树学习笔记)
- \(dfs\),这个...很基础吧。
- 对于每一个字符串,建立一张有向图,利用 拓扑排序 判断其是否有环,无环就输出。
对于每一个字符串,我们可以设它的字典序是所有字符串中最小的。
也就是说,这个字符串的第 \(i\) 个字母 在 \(trie\) 的第 \(i\) 层(根节点算第 \(0\) 层)的所有字母中 字典序最小。
设这个字符串的第 \(i\) 个字母为 \(u\),我们可以连单向边 \(u \to v\),表示我们指定了 \(u\) 的字典序比 \(v\) 小。(其中 \(v\) 是第 \(i\) 层的其它字母)
根据题目描述里的粗体部分,当在遍历时已有字母为单词结尾(即有前缀)可以直接返回 false。
当 \(26\) 个字母间的关系形成环时,也一定不能成为字典序最小的串。
代码实现
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<iostream>
#include<cstring>
#include<queue>
#define N 300010
using namespace std;
int n,trie[N][30],tot=1,ru[30],ans=0;
bool sum[N],flag[N],edge[30][30];
string s[N];
queue<int>q;
void insert(string x){
int p=1;
for(int i=0;i<x.size();i++){
int ch=x[i]-'a';
if(!trie[p][ch]) trie[p][ch]=++tot;
p=trie[p][ch];
}
sum[p]=true;
return;
}
void topo(){
while(!q.empty()) q.pop();
for(int i=0;i<26;i++) if(!ru[i]) q.push(i);
while(!q.empty()){
int now=q.front();
q.pop();
for(int i=0;i<26;i++){
if(edge[now][i])
if(!(--ru[i])) q.push(i);
}
}
return;
}
bool ask(string x){
int p=1;
memset(edge,false,sizeof(edge));
memset(ru,0,sizeof(ru));
for(int i=0;i<x.size();i++){
if(sum[p]) return false;
int ch=x[i]-'a';
for(int j=0;j<26;j++){
if(ch!=j && trie[p][j] && !edge[ch][j]){
++ru[j];edge[ch][j]=true;
}
}
p=trie[p][ch];
}
topo();
for(int i=0;i<26;i++)
if(ru[i]) return false;
return true;
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
cin>>s[i];
insert(s[i]);
}
for(int i=1;i<=n;i++){
if(ask(s[i])){
ans++;flag[i]=true;
}
}
printf("%d\n",ans);
for(int i=1;i<=n;i++){
if(flag[i]) cout<<s[i]<<endl;
}
return 0;
}
结语
trie 树真是个好东西
完结撒花。
P3065 [USACO12DEC]First! G的更多相关文章
- [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一直在研究字符串.她发现 ...
- 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\)树上.之后检索每一个字符串的时候,我们看和他同一层的地方是否有字符,如 ...
- [USACO12DEC]第一!First! (Trie树,拓扑排序)
题目链接 Solution 感觉比较巧的题啊... 考虑几点: 可以交换无数次字母表,即字母表可以为任意形态. 对于以其他字符串为前缀的字符串,我们可以直接舍去. 因为此时它所包含的前缀的字典序绝对比 ...
- Storyboards Tutorial 03
这一节主要介绍segues,static table view cells 和 Add Player screen 以及 a game picker screen. Introducing Segue ...
- 文件图标SVG
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink ...
- [bzoj3012][luogu3065][USACO12DEC][第一!First!] (trie+拓扑排序判环)
题目描述 Bessie has been playing with strings again. She found that by changing the order of the alphabe ...
- Milk Pumping G&Milk Routing S 题解
Milk Pumping G&Milk Routing S 双倍经验时间 洛谷P5837 [USACO19DEC]Milk Pumping G 洛谷P3063 [USACO12DEC]Milk ...
随机推荐
- Oracle 11G RAC11.2.0.4 + Redhat7.3安装手册
安装思路: 1.安装两台redhat7 linux系统 2.网络配置(双网卡,public,vip,private,scan) 3.存储配置(内存配置,ASM共享存储:6块5G共享盘udev,根目录留 ...
- 结合实体框架(代码优先)、工作单元测试、Web API、ASP. net等,以存储库设计模式开发示例项目。NET MVC 5和引导
介绍 这篇文章将帮助你理解在库模式.实体框架.Web API.SQL Server 2012.ASP中的工作单元测试的帮助下设计一个项目.净MVC应用程序.我们正在开发一个图书实体和作者专用的样例图书 ...
- Hadoop框架:NameNode工作机制详解
本文源码:GitHub·点这里 || GitEE·点这里 一.存储机制 1.基础描述 NameNode运行时元数据需要存放在内存中,同时在磁盘中备份元数据的fsImage,当元数据有更新或者添加元数据 ...
- devops-持续集成管理之SonarQube
1. devops-持续集成管理之SonarQube 1) 代码质量七宗罪 编码规范:是否遵守了编码规范,遵循了最佳实践. 潜在的BUG:可能在最坏情况下出现问题的代码,以及存在安全漏洞的代码. 文 ...
- 多测师讲解python_模块(导入模块和内置模块)_高级讲师肖sir
#自定义模块# from aaa import * #指定导入某个包中具体的类.函数.方法## A.fun1(2,2) #import +模块名 :# # import +模块名+.+.+# # 导入 ...
- Rust之路(2)——数据类型 上篇
[未经书面同意,严禁转载] -- 2020-10-13 -- Rust是系统编程语言.什么意思呢?其主要领域是编写贴近操作系统的软件,文件操作.办公工具.网络系统,日常用的各种客户端.浏览器.记事本. ...
- RDS 事务型数据库sql
-- 替换json中数据 select SUBSTRING_INDEX(SUBSTRING_INDEX('[{"channelCode":"MOBIL",&qu ...
- 新手学习C语言/C++编程你所必须要了解的知识!从计算机原理开始!
C语言是面向过程的,而C++是面向对象的 C和C++的区别: C是一个结构化语言,它的重点在于算法和数据结构.C程序的设计首要考虑的是如何通过一个过程,对输入(或环境条件)进行运算处理得到输出(或实现 ...
- wine实用经验教程
本篇讲类unix系统下的用以模拟运行Windows程序的wine.会从普通使用者的比较实用的角度去讲.有专为国内用户准备的内容. 本篇面向有Linux经验但对wine不熟悉的人. wine可靠吗?该不 ...
- ASP.NET Core 3.1 Razor 视图预编译、动态编译
1.安装NuGet包 Install-Package Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation 2.Startup.cs 配置 public ...