题意描述

[USACO12DEC]First! G

不错的一道题。

给你 \(N\) 个字符串,要求你求出可能的字典序最小的字符串。

对于 可能的最小的字符串,你可以任意排列 \(26\) 个字母,使得其字典序最小。

举个栗子:(好像就是样例)

4
omm
moo
mom
ommnom

首先明确一点:当一个单词为另一个单词的前缀时,较长的单词不可能为字典序最小的

然后发现:

  1. 我们可以使用标准字母表使 mom 排在第一个。(即字典序最小)
  2. 也可以使用字母表 abcdefghijklonmpqrstuvwxyz 使得 omm 排在第一个。

就是酱紫。

算法分析

字符串让人联想到 \(trie\) 树,优先级关系让人联想到 拓扑排序,于是就解决了。

  1. 建立一颗 \(trie\) 树。(有需要的可以看看 trie 树学习笔记
  2. \(dfs\),这个...很基础吧。
  3. 对于每一个字符串,建立一张有向图,利用 拓扑排序 判断其是否有环,无环就输出。

对于每一个字符串,我们可以设它的字典序是所有字符串中最小的。

也就是说,这个字符串的第 \(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的更多相关文章

  1. [luogu P3065] [USACO12DEC]第一!First!

    [luogu P3065] [USACO12DEC]第一!First! 题目描述 Bessie has been playing with strings again. She found that ...

  2. 洛谷P3065 [USACO12DEC]第一!First!(Trie树+拓扑排序)

    P3065 [USACO12DEC]第一!First! 题目链接:https://www.luogu.org/problemnew/show/P3065 题目描述 Bessie一直在研究字符串.她发现 ...

  3. P3065 [USACO12DEC]第一!First!

    题目描述 Bessie has been playing with strings again. She found that by changing the order of the alphabe ...

  4. Luogu P3065 [USACO12DEC]第一!First!【字典树/拓扑排序】By cellur925

    题意:给你许多字符串,你可以改变字母序大小,问有哪些字符串可能成为字典序最小的字符串. 我们考虑把这些字符串都塞到\(trie\)树上.之后检索每一个字符串的时候,我们看和他同一层的地方是否有字符,如 ...

  5. [USACO12DEC]第一!First! (Trie树,拓扑排序)

    题目链接 Solution 感觉比较巧的题啊... 考虑几点: 可以交换无数次字母表,即字母表可以为任意形态. 对于以其他字符串为前缀的字符串,我们可以直接舍去. 因为此时它所包含的前缀的字典序绝对比 ...

  6. Storyboards Tutorial 03

    这一节主要介绍segues,static table view cells 和 Add Player screen 以及 a game picker screen. Introducing Segue ...

  7. 文件图标SVG

    ​<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink ...

  8. [bzoj3012][luogu3065][USACO12DEC][第一!First!] (trie+拓扑排序判环)

    题目描述 Bessie has been playing with strings again. She found that by changing the order of the alphabe ...

  9. Milk Pumping G&Milk Routing S 题解

    Milk Pumping G&Milk Routing S 双倍经验时间 洛谷P5837 [USACO19DEC]Milk Pumping G 洛谷P3063 [USACO12DEC]Milk ...

随机推荐

  1. Centos-退出抽取设备-eject

    eject 退出抽取设备,如光驱或磁带,如果设备已经挂载,则卸载设备 相关选项 -q 退出磁盘 -r 退出光盘 -d 显示默认设备

  2. Python-输入输出-input ouput

    输入.输出? 这种统称为IO流,也就是数据流向,在标准中,从终端输入称为标准输入 sidin,从终端输出为标准输出 stdout,从终端错误输出则为标准错误输出 stderr.这些只是IO流中终端方面 ...

  3. Mysql安装(解压版)

    文章首推 刷网课请点击这里 刷二级请点击这里 论文查重请点击这里 WIFI破解详细教程 今日主题:Mysql安装(解压版) 环境 系统:windows10 版本:mysql5.7.29 安装过程 1. ...

  4. 玩转Libmodbus(一) 搭建开发环境

    这篇文章是转载的,我主要是参考了其搭建环境的部分. 转载自: https://blog.csdn.net/qq_40452910/article/details/88560310 一.源码下载 1.l ...

  5. 小伙伴想学Jenkins自动构建发布项目,我:安排上了!!

    写在前面 趁着十一长假,很多小伙伴都在悄悄学习,有些是为了能够顺利通过面试,进入大厂升职加薪.有些则是为了进一步巩固和提高自己的专业技能,希望有朝一日能过成为互联网架构师乃至技术专家.这不,就有小伙伴 ...

  6. c++ 动态库的加载

    转载:https://blog.csdn.net/ztq_12345/article/details/99677769 使用ide是vs, 使用Windows.h下的3个函数对动态库进行加载第一个:H ...

  7. DevOps元素周期表—2号元素Kibana

    Kibana 是一款开源的数据分析和可视化平台,它是 Elastic Stack 成员之一,设计用于和 Elasticsearch 协作.您可以使用 Kibana 对 Elasticsearch 索引 ...

  8. Flutter沉浸式状态栏/AppBar导航栏/仿咸鱼底部凸起导航

    Flutter中如何实现沉浸式透明Statusbar状态栏效果? 如下图:状态栏是指android手机顶部显示手机状态信息的位置.android 自4.4开始新加入透明状态栏功能,状态栏可以自定义颜色 ...

  9. 【硬核】Dubbo常见面试题

    有情怀,有干货,微信搜索[三太子敖丙]关注这个不一样的程序员. 本文 GitHub https://github.com/JavaFamily 已收录,有一线大厂面试完整考点.资料以及我的系列文章. ...

  10. coder初入职场必备:Eclipse+Tomcat8+MAVEN+SVN 工作环境搭建

    1.JDK的安装 首先下载JDK,这个从sun公司官网可以下载,根据自己的系统选择64位还是32位,安装过程就是next一路到底.安装完成之后当然要配置环境变量了. ----------------- ...