codeforces 886D. Restoration of string (字符串处理+类拓扑排序)
2017-12-04 20:05
316 查看
搞了好久的题,现在看到这个题有点恶心,先让我缓缓……
传送门:codeforces 886D
题目大意:
给出 n 个字符串,求一个结果串,使得这 n 个字符串都是结果串中出现频率最高的子串。如果存在则输出字典序最小的结果串,反之就输出 NO。
思路:
由于 n 个字符串都是结果串中出现频率最高的子串,其出现频率为 1,就说明结果串中不存在相同的 2 个子串,不然的话该相同的子串就是出现频率最高的子串了。
先来考虑输出 NO 的情况:
1.在同一个字符串中出现至少 2 个相同的字符。根据上面说的应该很好理解。
2.在所有字符串中存在某个字符 x 的后继字符不止一个。也就是存在分支。
3.在所有字符串中存在某个字符 x 的前驱字符不止一个。也就是存在分支。
4.在所有字符串中存在环,例如以下两个字符串:“ab”、“ba”。
其实看到这个题 n 最大 10^5,容易被唬到,我们来分析一下。从上面的分析可以知道结果串最多有 26 个字符(字符各不相同),那么 26 个字符的字符串有多少个子串呢? 长度为 1 的有 26个,长度为 2 的有 25 个 …… 长度为 26 的有 1 个。共:1+2+3+……+26 = (26+1) * 27 / 2 = 351 个。所以 n > 351 的直接输出 NO 即可。
下面再来考虑存在结果串的情况下怎么求出这个结果串呢?由于前面说过每个字符的后继字符都是确定的,我们可以从第一个字符(即入度为 0 的字符)开始得到几个字符形成的字符链。这些字符链按照字典序升序排列组成的字符串就是结果。
至于判断输出 NO 的时候怎样求出度和入度,这里可以先按照字符关系建图再求出度和入度,一边输入一边求容易把相同的边重复计算。至于判断是否有环,可以在求完后字符后把每个字符的后继走一遍,如果有字符走过多次则存在环。
P个S: 我个人觉得直接对字符链升序排列然后输出是不对的……单个升序能保证组成的字符串也是升序吗?没证明过……当时先按照以下排序方式交了一发,当然是正确的了,但是比直接升序排列的时间要高一点点。
PPS:想明白为什么直接升序排列就可以了,因为所有的字符只出现一次,所以直接按升序排列只适用于本题。
代码:
这次的代码有点乱,因为是自己在不断的解决每一步的过程中不断修改的……
传送门:codeforces 886D
题目大意:
给出 n 个字符串,求一个结果串,使得这 n 个字符串都是结果串中出现频率最高的子串。如果存在则输出字典序最小的结果串,反之就输出 NO。
思路:
由于 n 个字符串都是结果串中出现频率最高的子串,其出现频率为 1,就说明结果串中不存在相同的 2 个子串,不然的话该相同的子串就是出现频率最高的子串了。
先来考虑输出 NO 的情况:
1.在同一个字符串中出现至少 2 个相同的字符。根据上面说的应该很好理解。
2.在所有字符串中存在某个字符 x 的后继字符不止一个。也就是存在分支。
3.在所有字符串中存在某个字符 x 的前驱字符不止一个。也就是存在分支。
4.在所有字符串中存在环,例如以下两个字符串:“ab”、“ba”。
其实看到这个题 n 最大 10^5,容易被唬到,我们来分析一下。从上面的分析可以知道结果串最多有 26 个字符(字符各不相同),那么 26 个字符的字符串有多少个子串呢? 长度为 1 的有 26个,长度为 2 的有 25 个 …… 长度为 26 的有 1 个。共:1+2+3+……+26 = (26+1) * 27 / 2 = 351 个。所以 n > 351 的直接输出 NO 即可。
下面再来考虑存在结果串的情况下怎么求出这个结果串呢?由于前面说过每个字符的后继字符都是确定的,我们可以从第一个字符(即入度为 0 的字符)开始得到几个字符形成的字符链。这些字符链按照字典序升序排列组成的字符串就是结果。
至于判断输出 NO 的时候怎样求出度和入度,这里可以先按照字符关系建图再求出度和入度,一边输入一边求容易把相同的边重复计算。至于判断是否有环,可以在求完后字符后把每个字符的后继走一遍,如果有字符走过多次则存在环。
P个S: 我个人觉得直接对字符链升序排列然后输出是不对的……单个升序能保证组成的字符串也是升序吗?没证明过……当时先按照以下排序方式交了一发,当然是正确的了,但是比直接升序排列的时间要高一点点。
int cmp(string a,string b) { return a+b<b+a; }
PPS:想明白为什么直接升序排列就可以了,因为所有的字符只出现一次,所以直接按升序排列只适用于本题。
代码:
这次的代码有点乱,因为是自己在不断的解决每一步的过程中不断修改的……
#include<iostream> #include<algorithm> #include<string> #include<string.h> using namespace std; string s,ans[28]; int main() 9d71 { int i,j,n,f,x,len; int vis[28],chu[28],ru[28],mp[28][28]; while(cin>>n) { f=1; memset(mp,0,sizeof(mp)); //字符构成的图 memset(ru,-1,sizeof(ru)); //每个字符的入度 memset(chu,-1,sizeof(chu)); //每个字符的出度 //在下面这个循环中,chu/ru=0则说明字符出现过,chu/ru=-1则没出现过 for(i=0;i<n;i++) { cin>>s; //输入字符串 memset(vis,0,sizeof(vis)); //用于判断每个字符串中字符出现的次数 len=s.length(); vis[s[0]-'a']++; //首个字符出现次数+1 ru[s[0]-'a']=0; //首个字符出现过 chu[s[0]-'a']=0; //首个字符出现过 for(j=1;j<len;j++) { //从第 1 个字符开始建图 int u=s[j-1]-'a'; //前一字符 int v=s[j]-'a'; //当前字符 mp[u][v]=1; vis[v]++; if(vis[v]>1) f=0; //如果出现次数>1,则输出 NO ru[v]=0; chu[v]=0; } } int next[28]; //每个字符的后继字符 memset(next,-1,sizeof(next)); for(i=0;i<26;i++) for(j=0;j<26;j++) if(mp[i][j]) { //如果存在边 ru[j]++; //入度+1 chu[i]++; //出度+1 next[i]=j; //记录后继 } for(i=0;i<26;i++) if(ru[i]>1||chu[i]>1) { //如果有字符的出度或入度 >1则输出 NO f=0; break; } for(i=0;i<26;i++) { //判断是否有环 x=i; memset(vis,0,sizeof(vis)); while(x!=next[x]) { if(vis[x]==1) { //如果当前元素访问过则有环 f=0; break; } vis[x]=1; x=next[x]; } } if(n>351 || !f) { cout<<"NO"<<endl; continue; } int tol=0; for(i=0;i<26;i++) //遍历 26个字符 if(ru[i]==0) { //如果入度为 0,则会形成一串字符 ans[tol]='a'+i; x=i; while(next[x]!=-1) { //加入后继字符 char c=next[x]+'a'; ans[tol]+=c; x=next[x]; } tol++; } sort(ans,ans+tol); //排序 for(i=0;i<tol;i++) cout<<ans[i]; cout<<endl; } return 0; }
相关文章推荐
- CodeForces 23A You're Given a String...(字符串处理)
- string字符串常用处理方法
- String内部函数-用于处理字符串
- hdu4821 string 字符串 哈希处理
- NSString / NSMutableString 字符串处理,常用代码
- UVa10391 string字符串处理
- NSString / NSMutableString 字符串处理,常用代码 (实例)
- String字符串处理
- C/C++字符串处理(2):String - 常字符串
- 字符串处理函数(string.h)
- Seoul 2006 / UVa 1368 DNA Consensus String (字符串处理)
- Codeforces 448B (字符串简单处理,读题)
- NSString / NSMutableString 字符串处理,常用代码 (实例)
- PHP - Manual手册 - CLXI. String 字符串处理函数 - str_pad使用另一个字符串将一个字符串填充到指定长度
- CodeForces 4C Registration system(字符串处理 | map)
- 巧妙处理StringBuilder.AppendFormat 方法中字符串含有花括号“{}”
- uva 1368 - DNA Consensus String(字符串处理)
- Gson解析或者转换对象成json字符串时,String为NULL转空字符串处理方案
- python 字符串string 处理函数
- Prototype源码浅析——String部分(三)之HTML字符串处理