• Codeforces Round #423 Div. 2 C. String Reconstruction(瞎搞)


    题目链接:Codeforces Round #423 Div. 2 C. String Reconstruction

    题意:

    给你n个子串和出现的位置,让你还原出字典序最小的原串。

    数据保证至少有一个解。

    题解:

    先将所有的串用标号的方式存起来。

    然后用将每个子串的出现位置放进对应的桶里。

    两个子串ab的位置一共有三种情况:(只考虑a的起点大于b的起点)

    一:ab不重叠。

    二:ab部分重叠。

    三:a子串完全包含后面b子串。

    然后开一个标记记录上个出现的子串。

    然后扫描整个ans,对于一,二种情况需要更新一下标记。

    然后如果当前位置能被上一个出现的子串覆盖,就用上个子串来覆盖。

    如果不能就赋值‘a’。

    时间复杂度O(maxlen+sum(k))。

     1 #include<bits/stdc++.h>
     2 #define F(i,a,b) for(int i=a;i<=b;++i)
     3 using namespace std;
     4 typedef pair<int,int>P;
     5 
     6 const int N=2e6+7;
     7 P a[N];
     8 char s[N],ans[N];
     9 int now=1,n,k,x,ed,mx;
    10 vector<int>g[N];
    11 
    12 int main(){
    13     scanf("%d",&n);
    14     F(i,1,n)
    15     {
    16         scanf("%s%d",s+now,&k);
    17         int len=strlen(s+now);
    18         a[i]=P(now,len);
    19         now+=len;
    20         F(j,1,k)
    21         {
    22             scanf("%d",&x);
    23             mx=max(mx,x+len-1);
    24             g[x].push_back(i);
    25         }
    26     }
    27     int pre=0,idx=0;
    28     F(i,1,mx)
    29     {
    30         for(int &it:g[i])
    31         {
    32             if(a[it].second+i>a[pre].second+idx)
    33                 pre=it,idx=i;
    34         }
    35         if(a[pre].second+idx-1>=i)ans[i]=s[a[pre].first+i-idx];
    36         else ans[i]='a';
    37     }
    38     printf("%s
    ",ans+1);
    39     return 0;
    40 }
    View Code
  • 相关阅读:
    MySQL版本详解
    数据库安全[一]
    python itertools模块学习
    两列布局实例
    Linux 原始套接字抓包实例
    [转]Linux终端快捷键
    SQL中的LEFT JOIN 和 RIGHT JOIN 以及INNER JOIN
    twisted框架入门笔记(1)
    一个关于lambda的题目
    找出数组中仅仅一个出现两次的数
  • 原文地址:https://www.cnblogs.com/bin-gege/p/7163205.html
Copyright © 2020-2023  润新知