当前位置:网站首页>洛谷P3065 [USACO12DEC]First! G 题解
洛谷P3065 [USACO12DEC]First! G 题解
2022-07-03 14:15:00 【q779】
洛谷P3065 [USACO12DEC]First! G 题解
题目链接:P3065 [USACO12DEC]First! G
题意:
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前。
∑ ∣ S i ∣ ≤ 3 × 1 0 5 \sum \left|S_i\right| \le 3 \times 10^5 ∑∣Si∣≤3×105
显然trie树存字符串
对于每个字符串,我们都假设它可以成为最小字典序的字符
然后依次遍历它的每个字符,尽可能让它们成为最小的
具体的,对于字符 u u u ,如果我们想让它比 v v v 字典序小,
我们可以把 u u u 向 v v v 连一条有向边
显然无解的情况会成环,这个可以用topo来判
值得注意的是,如果一个串的子串也在输入数据中存在,那么它一定无解
时间复杂度 O ( 26 × ∑ ∣ S i ∣ ) O(26 \times \sum |S_i|) O(26×∑∣Si∣)
代码:
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <iomanip>
#include <queue>
using namespace std;
#define int long long
#define INF 0x3f3f3f3f3f3f3f3f
#define N (int)(3e4+15)
#define M (int)(3e5+15)
int n,ans;
string s[N];
bool ok[N];
struct Trie
{
int tot,trie[M][26],ed[M],e[35][35],in[26];
queue<int> q;
void insert(string str)
{
int u=0;
for(int i=0; i<str.size(); i++)
{
int c=str[i]-'a';
if(!trie[u][c])trie[u][c]=++tot;
u=trie[u][c];
}
ed[u]=1;
}
void topo()
{
while(!q.empty())q.pop();
for(int i=0; i<26; i++)
if(!in[i])q.push(i);
while(!q.empty())
{
int u=q.front();q.pop();
for(int c=0; c<26; c++)
if(e[u][c]&&(!(--in[c])))
q.push(c);
}
}
bool solve(string str)
{
int u=0;
memset(e,0,sizeof(e));
memset(in,0,sizeof(in));
for(int i=0; i<str.size(); i++)
{
if(ed[u])return 0;
int c=str[i]-'a';
for(int j=0; j<26; j++)
{
if(j!=c&&trie[u][j]&&!e[c][j])
e[c][j]=1,++in[j];
}
u=trie[u][c];
}
topo();
for(int i=0; i<26; i++)
if(in[i])return 0;
return 1;
}
}tr;
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
// freopen("check.in","r",stdin);
// freopen("check.out","w",stdout);
cin >> n;
for(int i=1; i<=n; i++)
{
cin >> s[i];
tr.insert(s[i]);
}
for(int i=1; i<=n; i++)
if(tr.solve(s[i]))
{
++ans;
ok[i]=1;
}
cout << ans << '\n';
for(int i=1; i<=n; i++)
if(ok[i])cout << s[i] << '\n';
return 0;
}
转载请说明出处
边栏推荐
- Why is this error reported when modifying records in the database
- etcd集群权限管理和账号密码使用
- 如何查询淘宝天猫的宝贝类目
- 适用于XP的DDK
- js . Find the first palindrome string in the array
- 7-11 calculation of residential water charges by sections
- Exercise 7-6 count capital consonants
- Understanding of closures
- [clean up the extraordinary image of Disk C]
- Solve the problem of dormitory router campus network sharing login
猜你喜欢
Fabric. JS document
Exercise 6-2 using functions to sum special A-string sequences
分布式事务(Seata) 四大模式详解
常见问题之PHP——ldap_add(): Add: Undefined attribute type in
Solution to failure or slow downloading of electron when electron uses electron builder to package
Understanding of closures
Interface for querying IP home
retrofit
Page generation QR code
Understand the application scenario and implementation mechanism of differential segment
随机推荐
Exercise 10-1 judge the three digits that meet the conditions
Solution to failure or slow downloading of electron when electron uses electron builder to package
NPM install is stuck with various strange errors of node NPY
7-20 print 99 formula table (format output)
中国PETG市场预测及战略研究报告(2022版)
7-9 find a small ball with a balance
Canvas utility library fabric JS user manual
js . Find the first palindrome string in the array
Interface for querying IP home
Learn to punch in today
7-10 calculate salary
7-11 calculation of residential water charges by sections
2021年区域赛ICPC沈阳站J-Luggage Lock(代码简洁)
PCB中常用快捷键
修改数据库中的记录为什么报这个错
数学常数表 by q779
适用于XP的DDK
[Jilin University] information sharing of postgraduate entrance examination and re examination
SSH access control, blocking the IP when logging in repeatedly to prevent brute force cracking
DDK for XP