bzoj3012[Usaco2012 Dec]First! 一号单词

2024-05-12 00:08

本文主要是介绍bzoj3012[Usaco2012 Dec]First! 一号单词,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3012

题目大意:

给n个字符串,问如果重新定义英文字符的顺序(就是重定义字典序),有哪些单词可能排在字典的第一名
举例来说,假设有四个单词:omm,moo,mom 和ommnom,如果奶牛定义o 在m 之前,则omm 可排第一,如果定义m 在o 之前,则mom 可排第一,但余下两个单词是无论如何不可能排在第一的。


题解:

trie+拓扑

辣鸡的OxQ自以为trie+贪心能轻松一A,结果只有一半的分,啊一定是哪里又sb打错了,调调调!what???数据辣磨大???不怕!调调调!于是调了一下午QwQ讲真,眼睛都花了,感觉离近视不远了。。。当我调出来的时候。。(我真的调出来了)发现想法有bugQwQ不能贪心QwQ啊悲伤

==============正解分割线===============

按输入建trie树啦。

对于一个字符串来说,要想排第一,首先没有其他的字符串是它的前缀,那么就走一下字典树,遇到了标记的话就说明有人是它前缀,就直接判断为不可以啊。

其次的话,它字符的优先度要比和它有着相同前缀的高。也就是说,在同一个父亲下,这个儿子要比其他兄弟的优先度高。那么我们就连一条有向边,设为x->y表示x的优先度比y高。如果出现环就说明有矛盾啊,冲突了,就不可以了。

没想到每一个串的长度不超过20..以为要开三万*三十万再见

搞的我都不敢用字符数组存.输入的时候.把所有串都连到了一起,记录了每个串的长度之后,每次处理都搞什么起始位置啊烦死!输出的时候就一个一个字符输出,,慢出天际!然后我就交去bzoj上卡评测了8s多倒数第二..我简直佩服自己。讲真,知道能开三万*20之后,改了交,六百多毫秒..差得不是一点半点!瞬间Rank10...(所以拿我代码对拍的时候不要出20+的字符串 不然帮我把注释删了弄回八秒多那个 此处@GDXB

下面代码里屏蔽的就是那个八秒多的输入输出和处理,标记起始位置的那个st我还没删,感受一下我的怨念!

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<queue>
#include<algorithm>
#include<iostream>
using namespace std;
#define maxn 300010
#define N 30010struct node
{int son[26];bool cnt;
}tr[maxn];int tlen;
int len[N];
char s[N][20];
//char s[maxn+N];
int sum,rt,rk[30];
void insert(int c,int st)
{int i,now=rt;len[c]=strlen(s[c]);// len[c]=strlen(s)-sum;for (i=0;i<len[c];i++){int k=s[c][i]-'a';// int k=s[i+st]-'a';if (tr[now].son[k]!=0) now=tr[now].son[k];else {tr[now].son[k]=++tlen;now=tlen;}}tr[now].cnt=1;
}
queue<int > q;
bool v[30][30];
int ru[30],chu[30][30];//入度 出度及连出去的边
bool top()
{int cnt=0;for (int i=0;i<26;i++) if (!ru[i]) {q.push(i);cnt++;}while (!q.empty()){int x=q.front();q.pop();for (int i=1;i<=chu[x][0];i++)if (ru[chu[x][i]]){ru[chu[x][i]]--;if (!ru[chu[x][i]]) {q.push(chu[x][i]);cnt++;}}}if (cnt==26) return true;return false;
}
bool bub(int c,int st)//走一下trie树
{int now=rt,i=0,j;for (i=0;i<len[c];i++){int k=s[c][i]-'a';// int k=s[i+st]-'a';if (tr[now].cnt) return false;//发现有标记了for (j=0;j<26;j++) if (j!=k && tr[now].son[j]!=0) if (!v[k][j]){v[k][j]=1;chu[k][++chu[k][0]]=j;ru[j]++;}now=tr[now].son[k];}return true;
}
bool bo[N];
int main()
{//freopen("first.in","r",stdin);//freopen("first.out","w",stdout);int n,i,st,cnt;scanf("%d",&n);tlen=rt=1;sum=st=0;for (i=1;i<=n;i++){scanf("%s",s[i]);// scanf("%s",s+sum);insert(i,st);// sum+=len[i];st=sum;}cnt=0;//st=0;memset(bo,false,sizeof(bo));for (i=1;i<=n;i++){memset(v,0,sizeof(v));memset(ru,0,sizeof(ru));memset(chu,0,sizeof(chu));if (bub(i,st)){if (top()) {cnt++;bo[i]=true;}}//st+=len[i];}//st=0;printf("%d\n",cnt);for (i=1;i<=n;i++){if (bo[i]){printf("%s",s[i]);// for (int j=st;j<st+len[i];j++) // printf("%c",s[j]);printf("\n");}// st+=len[i];}return 0;
}


这篇关于bzoj3012[Usaco2012 Dec]First! 一号单词的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/981049

相关文章

每日一练7:简写单词(含链接)

1.链接 简写单词_牛客题霸_牛客网 2.题目 3.代码1(错误经验) #include <iostream>#include <string>using namespace std;int main() {string s;string ret;int count = 0;while(cin >> s)for(auto a : s){if(count == 0){if( a <=

动态规划---单词拆分

题目: 给你一个字符串 s 和一个字符串列表 wordDict 作为字典。如果可以利用字典中出现的一个或多个单词拼接出 s 则返回 true。 注意:不要求字典中出现的单词全部都使用,并且字典中的单词可以重复使用。 思路:本题属于完全背包问题,字符串s的长度为背包容量,字符串列表wordDict中的每一个元素相当于物品。 动态规划五部曲: 1.确定dp数组及含义 dp数组为元素类型是布

广度优先搜索Breadth-First-Search

目录  1.问题 2.算法 3.代码 4.参考文献  1.问题         广度优先搜索,稍微学过算法的人都知道,网上也一大堆资料,这里就不做过多介绍了。直接看问题,还是从下图招到一条从城市Arad到Bucharest的路径。  该图是连通图,所以必然存在一条路径,只是如何找到最短路径。 2.算法 还是贴一个算法的伪代码吧: 1 procedu

WPS如何查看已添加到词典的单词

WPS Office(12.1.0.17827) ① 点击文件,在文件中找到选项 ② 找到拼写检查并点击自定义词典 ③ 如果要删除已添加到词典的"错词",则点击修改 ④ 选择"错词", 点击删除

【C】单词长度

课程:程序设计入门——C语言(翁恺) 题目内容: 你的程序要读入一行文本,其中以空格分隔为若干个单词,以‘.’结束。你要输出这行文本中每个单词的长度。这里的单词与语言无关,可以包括各种符号,比如“it's”算一个单词,长度为4。注意,行中可能出现连续的空格。 输入格式: 输入在一行中给出一行文本,以‘.’结束,结尾的句号不能计算在最后一个单词的长度内。 输出格式: 在一行中输出这行

代码随想录第八天|151.翻转字符串里的单词 卡码网:55.右旋转字符串 28. 实现 strStr() 459.重复的子字符串

反转字符串的单词 思路:刷过稍微忘记 class Solution {public://去除空格string remove(string s){//使用快慢指针int slow=0;int i=0;for(;i<s.size();i++){if(s[i]!=' '){if(slow!=0){s[slow++]=' ';}while(s[i]!=' '&&i<s.size()){s[slow+

LeetCode - 41. First Missing Positive

41. First Missing Positive  Problem's Link  ---------------------------------------------------------------------------- Mean:  给你一组整数,找出第一个空缺的正整数. 要求:时间O(n),空间O(n). analyse: 这题时间O(n)想了

实操在聆思CSK6大模型开发板的英文评测SDK中自定义添加单词、短语、句子资源

引言 英文评测示例通过对用户语音输入的英文单词进行精准识别,提供 单词、短语、句子 三种类型,用户在选择好类型后,可根据屏幕上的提示进行语音输入,评测算法将对输入的英文语音进行精准识别,并对单词的发音、错读、漏读、多读等方面进行评估。 本文将详细介绍在聆思CSK6大模型语音视觉开发板上,如何替换英文评测示例中的单词、短语和句子,从而让您有更好的AI应用体验。 ·· 获取英文评测SDK 部

我用ChatGPT编写一个英语猜单词游戏源码

一、背景 我们可以利用python中的tkinter框架创建一个简单的英语单词猜词游戏。用户将看到一个缺少几个字母的单词,并需要填写出正确的字母,填写正确后会提醒correct,错误则提示:try again. 本代码全程利用VScode中的ChatGPT插件来完成。 二、实现过程 步骤 1:导入必要的库 我们需要导入 tkinter 库来创建图形用户界面(GUI),还需要导入 rando

【算法】单词出现次数和位置统计

【算法】单词出现次数和位置统计 题目描述 编写一个程序,用于统计一个给定单词在一段文本中出现的次数以及第一次出现的位置。如果单词在文本中出现,则输出出现次数和第一次出现的位置(位置从0开始计算)。如果单词没有出现,则输出-1。 思路分析 使用Scanner类从控制台读取两个字符串:要搜索的文本str和要统计的单词substring。定义一个方法countStr,该方法接收两个字符串参数