zoukankan      html  css  js  c++  java
  • [bzoj4974] 字符串大师

    题解:给出一个字符串s,定义per_i为s_i的长度为i的前缀的最小循环节,现在给出per_i (i=1~n),要求你还原字符串s,s的字典序要求最小

    题解:

    per_i=i-next_i,但是好像跟此题没有太大的关系

    分两种情况讨论:

    1、i==per_i,相当于知道循环节和循环串要求后面某个位置的字符,那么直接从之前的循环串推过来即可

    2、i!=per_i,表示不能参与到之前的循环串中,类似于next数组的构造,记录下哪些字符在循环串中出现过,删去后从小到大取即可

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstdlib>
     4 #include<cstring>
     5 #include<algorithm>
     6 #include<cmath>
     7 #define ll long long
     8 #define N 100010
     9 using namespace std;
    10 
    11 int per[N];
    12 char s[N];
    13 bool vis[N];
    14 
    15 int gi() {
    16   int x=0,o=1; char ch=getchar();
    17   while(ch!='-' && (ch<'0' || ch>'9')) ch=getchar();
    18   if(ch=='-') o=-1,ch=getchar();
    19   while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
    20   return o*x;
    21 }
    22 
    23 int main() {
    24   int n=gi();
    25   for(int i=1; i<=n; i++) per[i]=gi();
    26   s[1]='a';
    27   for(int i=2; i<=n; i++) {
    28     if(i!=per[i]) s[i]=s[(i-1)%per[i]+1];
    29     if(i==per[i]) {
    30       memset(vis,0,sizeof(vis));
    31       int j=i-1;
    32       while(j!=per[j]) {
    33     j=(j-1)%per[j]+1;
    34     vis[s[j+1]-'a']=1;
    35       }
    36       for(int k=1; k<26; k++) {
    37     if(!vis[k]) {s[i]=k+'a';break;}
    38       }
    39     }    
    40   }
    41   printf("%s
    ", s+1);
    42   return 0;
    43 }
  • 相关阅读:
    C++读写文件并排序
    我的vim配置---jeffy-vim-v2.2.tar
    vim 代码注释插件
    我的vim配置---jeffy-vim-v2.1.tar
    linux中screen命令的用法
    Install and Enable Telnet server in Ubuntu Linux
    Telnet环境变量
    Telnet窗口尺寸选项
    TELNET终端类型选项
    Telnet技术白皮书
  • 原文地址:https://www.cnblogs.com/HLXZZ/p/7592615.html
Copyright © 2011-2022 走看看