[luogu P3065] [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].

给出n个字符串,问哪些串能在特定的字母顺序中字典序最小。

输入输出格式

输入格式:

  • 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.

输出格式:

  • 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: 复制

4
omm
moo
mom
ommnom
输出样例#1: 复制

2
omm
mom

说明

The example from the problem statement.

Only "omm" and "mom" can be ordered first.

来点不是很难又不是很水的题目。

这一题最开始的想法就是建一棵字典树trie,然后,对于每一个单词,沿着字典树中他的路径走下去。

那怎么判断是否可行?如果按照贪心的想法,比如当前的节点优先级设为剩下(除去前几个字母)最高的,这样显然会有反例。

那么,我们想,安排字母的顺序,优先级,我们想到了topo排序。

由于每一个节点下面,非当前路径上的点的优先级小于路径上的点,所以就可以建一条边。

在这里可以直接用邻接矩阵,更方便,且效率也没差到哪里(因为可能有很多边)。

然后,就进行topo排序了,如果可行就可以了。

还有需要注意的是,比如有两个字符串:

wzz

wzzlihai

那么,wzzlihai也不能以某种顺序排到第一位。

那这个怎么判呢?在每个单词结束的时候都在结束点打个“结束”标记。

然后询问时,如果路径上某一个点(非最后一个)上有“结束”标记,则return 0。

code:

 #pragma GCC optimize(2)
 #include <cstdio>
 #include <cstring>
 #include <algorithm>
 #include <iostream>
 #include <string>
 #include <queue>
 #define ms(a,x) memset(a,x,sizeof a)
 typedef long long LL;
 namespace fastIO {
     #define puc(c) putchar(c)
     inline int read() {
         ,f=; char ch=getchar();
         ') {
             if (ch=='-') f=-f;
             ch=getchar();
         }
         ') {
             x=(x<<)+(x<<)+ch-';
             ch=getchar();
         }
         return x*f;
     }
     template <) {
         T f=; char ch=getchar();
         ') {
             if (ch=='-') f=-f;
             ch=getchar();
         }
         ') {
             x=(x<<)+(x<<)+ch-';
             ch=getchar();
         }
         x*=f;
     }
     ];
     template <class T> inline void write(T x) {
         ) {
             puc(');
             return;
         }
         ) {
             x=-x;
             puc('-');
         }
         ; x; x/=) w[++cnt]=x%;
         );
     }
     inline void newline() {
         puc('\n');
     }
     inline void newblank() {
         puc(' ');
     }
 }
 namespace OJ{
     void Online_Judge() {
         #ifndef ONLINE_JUDGE
             freopen("in.txt","r",stdin);
             freopen("out.txt","w",stdout);
         #endif
     }
 }
 using std::string;
 using std::queue;
 ,L=,A=;
 int n,cnt,len[N]; bool vis[N]; string s[N]; char ss[L];
 int tot,f[A][A],dg[N];
 queue <int> q;
 #define TrieNode node
 class TrieNode {
     private:
         bool end; node *ch[A];
     public:
         node() {
             end=,ms(ch,);
         }
         inline bool topo() {
             while (!q.empty()) q.pop();
             ; i<A; ++i) {
                 ; j<A; ++j) {
                     if (f[i][j]) ++dg[j];
                 }
             }
             ; i<A; ++i) {
                 ) q.push(i);
             }
             ;
             for (int x; !q.empty(); ) {
                 x=q.front(),q.pop();
                 ; i<A; i++) {
                     if (f[x][i]) {
                         --dg[i];
                         ) q.push(i);
                     }
                 }
             }
             ; i<A; ++i) {
                 ) ;
             }
             ;
         }
         inline void insert(node *u,char a[],int l) {
             ,x; i<l; ++i) {
                 x=a[i]-'a';
                 ) {
                     u->ch[x]=new node();
                 }
                 u=u->ch[x];
             }
             u->end=;
         }
         inline bool reply(node *u,char a[],int l) {
             ms(f,),ms(dg,);
             ,x; i<l; ++i) {
                 x=a[i]-'a';
                 &&u->ch[x]->end) ;
                 ; j<; ++j) {
                     &&j!=x) f[x][j]=;
                 }
                 u=u->ch[x];
             }
             return topo();
         }
 }t,*rot;
 int main() {
     OJ::Online_Judge();
     scanf(,rot=new node();
     ; i<=n; ++i) {
         scanf("%s",ss),len[i]=strlen(ss);
         s[i]="";
         ; j<len[i]; ++j) {
             s[i]=s[i]+ss[j];
         }
         t.insert(rot,ss,len[i]);
     }
     ; i<=n; ++i) {
         ; j<len[i]; ++j) {
             ss[j]=s[i][j];
         }
         cnt+=vis[i]=t.reply(rot,ss,len[i]);
     }
     printf("%d\n",cnt);
     ; i<=n; ++i) {
         if (vis[i]) {
             ; j<len[i]; ++j) {
                 putchar(s[i][j]);
             }
             putchar('\n');
         }
     }
     ;
 }

[luogu P3065] [USACO12DEC]第一!First!的更多相关文章

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

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

  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. [USACO12DEC]第一!First! (Trie树,拓扑排序)

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

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

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

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

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

  7. luogu P3065 first——trie树相关

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

  8. 【[USACO12DEC]第一!First!】

    一个串不能成为第一的情况有两种 另外一个单词是它的前缀 在分配字母表大小关系的时候出现了矛盾的情况 第一种很好判断,一旦我们在一个单词没有匹配完之前遇到一个结束标志,那么就说明另外一个单词是它的前缀 ...

  9. 【luogu P3063 [USACO12DEC]牛奶的路由Milk Routing】 题解

    题目链接:https://www.luogu.org/problemnew/show/P3063#sub 我很好奇这道题为什么没被收入SPFA好题 #include <cstdio> #i ...

随机推荐

  1. Python在终端通过pip安装好包以后,在Pycharm中依然无法使用的解决办法

    在终端通过pip装好包以后,在pycharm中导入包时,依然会报错.新手不知道具体原因是什么,我把我的解决过程发出来. pip install 解决方案一: 在Pycharm中,依次打开File--- ...

  2. CLASS类继承

    单继承:# class People: 经典类class People(object): #新式类 def __init__(self,name,age,n=1000): self.name = na ...

  3. socket的原理和实验

    1.socket原理 根据连接启动的方式以及本地套接字要连接的目标,套接字之间的连接过程可以分为三个步骤:服务器监听,客户端请求,连接确认. (1)服务器监听:是服务器端套接字并不定位具体的客户端套接 ...

  4. ansible-2.1.0.0_module

    ansible --version ansible 2.1.0.0 config file = /home/onest/luoliyu/ceph-ansible/ansible.cfg configu ...

  5. toggle,hasClass

    toggle 但当toggle(),不带参数时,与show()和hide()的作用一样,切换元素的可见状态,如果元素是可见的,则切换为隐藏状态;如果元素是隐藏的则切换为可见状态,此时括号内可添加()毫 ...

  6. Literal绑定数据

    前台: <asp:Literal ID = "ChiCunShow" runat = "server"></asp:Literal> 后 ...

  7. React Native之常用组件(View)

    一. JSX和组件的概念 React的核心机制之一就是虚拟DOM:可以在内存中创建的虚拟DOM元素.React利用虚拟DOM来减少对实际DOM的操作从而提升性能.传统的创建方式是: 但这样的代码可读性 ...

  8. 【Diary】期中考+春游记

    4.22-4.24 期中考 周一 早上 赶来三楼电教厅自习,疯狂复习历史.想到下午考语文历史两大文科,不由得有点慌吧. 突然,沙雕体委说了一句: 下午考政治,你不背诵吗 下午 语文感觉正常发挥. 政治 ...

  9. poj 1321 棋盘问题 (DFS深度优先搜索)

    Problem Description 在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别.要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋 ...

  10. Matlab 将两个图像进行分离 已知其中一个图像

    5.下图(a)是一幅两个灰度图像合成的图像,已知其中一幅图像如图(b)所示,试把另一幅图像提取出来,并显示. 运用减法做 %加载入要处理的图片 A=imread('a.png'); %将I变为[0,1 ...