• [Codeforces Round #438][Codeforces 868D. Huge Strings]


    题目链接:868D - Huge Strings

    题目大意:有(n)个字符串,(m)次操作,每次操作把两个字符串拼在一起,并询问这个新串的价值。定义一个新串的价值(k)为:最大的(k),使得这个新串包含所有长度为(k)的01串(这样的字符串有(2^k)个)

    题解:首先来证明对于任何的串,这个(k)的值不会超过9

       若(k=10),由所有字符串的长度总和不超过100,因此在初始的(n)个串里,互不相同的长度为(k)的子串不超过100个。又由于每次连接最多能产生9个新的长度为(k)的子串(即横跨两个字符串之间的子串),因此互不相同的子串个数最多为(9 cdot100+100<2^k),故(k<10)

       接下来就只需要记录每个字符串的前缀,后缀以及长度为(k)的子串有哪些就好了。

    #include<bits/stdc++.h>
    using namespace std;
    #define N 101
    int n,m,a,b;
    struct rua
    {
        string st,ed;
        set<int>has[10];
        bool check(int k)
          {
          for(int i=0;i<(1<<k);i++)
            if(!has[k].count(i))return false;
          return true;
          }
        int ans()
          {
          for(int k=9;k>0;k--)
            if(check(k))return k;
          return 0;
          }
        rua connect(rua nxt)
          {
          rua res=nxt;
          res.st=st;
          if(st.size()<9)
            res.st=st+nxt.st.substr(0,min(nxt.st.size(),9-st.size()));
          int cpy_len=min(ed.size(),9-nxt.ed.size());
          if(nxt.ed.size()<9)
            res.ed=ed.substr(ed.size()-cpy_len,cpy_len)+nxt.ed;
          for(int k=1;k<=9;k++)
            for(auto i:has[k])res.has[k].insert(i);
          string tmp=ed+nxt.st;
          int len=tmp.size();
          for(int i=0;i<len;i++)
            {
            int value=0;
            for(int d=0;d<9 && i+d<len;d++)
              value=value*2+tmp[i+d]-'0',
              res.has[d+1].insert(value);
            }
          return res;
          }
    }f[2*N];
    string s;
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
          {
          cin>>s;
          int len=s.size();
          for(int j=0;j<len;j++)
            {
            int value=0;
            for(int d=0;d<9 && j+d<len;d++)
              value=value*2+s[j+d]-'0',
              f[i].has[d+1].insert(value);
            }
          int cpy_len=min(9,len);
          f[i].st=s.substr(0,cpy_len);
          f[i].ed=s.substr(len-cpy_len,cpy_len);
          }
        scanf("%d",&m);
        for(int i=1;i<=m;i++)
          {
          scanf("%d%d",&a,&b);
          f[n+i]=f[a].connect(f[b]);
          printf("%d
    ",f[n+i].ans());
          }
    }
    View Code
  • 相关阅读:
    上传文件
    Win10中英文的切换
    2015 4.15笔试
    wpf的学习日志(二)
    静态类
    面试宝典
    设计模式 --- 模型-视图-控制器(Model View Controller)
    设计模式 --- 单例模式(Singleton)
    iOS 应用架构浅谈
    (转)Block的使用
  • 原文地址:https://www.cnblogs.com/DeaphetS/p/9693580.html
Copyright © 2020-2023  润新知