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 ...
随机推荐
- Java学习day02
day02-课堂笔记 1.打开DOS命令窗口,执行java HelloWorld,执行原理? * java.exe命令会启动JVM * JVM启动之后会启动类加载器ClassLoader * Clas ...
- RTKLIB的主要功能
RTKLIB是全球导航卫星系统GNSS(global navigation satellite system)的标准&精密定位开源程序包,RTKLIB由日本东京海洋大学(Tokyo Unive ...
- CAD常用知识点
1.Ctrl+9:打开命令窗口: 2.删除标注或者其他(选择对象过滤器):输入fi后回车会出现对象选择过滤器窗口,以删除标注为例,点击选择过滤器-----标注 按以下顺序点击后回车, 框选要去掉的标注 ...
- CPU 执行程序的秘密,藏在了这 15 张图里
前言 代码写了那么多,你知道 a = 1 + 2 这条代码是怎么被 CPU 执行的吗? 软件用了那么多,你知道软件的 32 位和 64 位之间的区别吗?再来 32 位的操作系统可以运行在 64 位的电 ...
- 搭建zabbix+grafana监控
编写一件安装脚本 #!/bin/sh echo "\033[32;1m脚本作者:fage\033[0m" #sleep 10 zabbix_version=4.0.2 zabbix ...
- 常见的Mysql十款高可用方案
简介 我们在考虑MySQL数据库的高可用架构时,主要考虑如下几方面: 如果数据库发生了宕机或者意外中断等故障,能尽快恢复数据库的可用性,尽可能的减少停机时间,保证业务不会因为数据库的故障而中断. 用作 ...
- php中 ob_函数 例:ob_start();用法
ob,输出缓冲区,是output buffering的简称,而不是output cache.ob用对了,是能对速度有一定的帮助,但是盲目的加上ob函数,只会增加CPU额外的负担 ob的基本原则:如果o ...
- Spark 单机环境配置
概要 Spark 单机环境配置 JDK 环境配置 Spark 环境配置 python 环境配置 Spark 使用示例 示例代码 (order_stat.py) 测试用的 csv 文件内容 (order ...
- 从源码角度来分析线程池-ThreadPoolExecutor实现原理
作为一名Java开发工程师,想必性能问题是不可避免的.通常,在遇到性能瓶颈时第一时间肯定会想到利用缓存来解决问题,然而缓存虽好用,但也并非万能,某些场景依然无法覆盖.比如:需要实时.多次调用第三方AP ...
- Go net/http包
net/http包 net/http是Go语言的内置包,它可以来创建HTTP客户端与服务端. 并且由net/http包创建的服务端性能十分高效,甚至不用nginx部署. client端 GET请求 以 ...