zoukankan      html  css  js  c++  java
  • 【数轴涂色+并查集路径压缩+加速】C. String Reconstruction

    http://codeforces.com/contest/828/problem/C

    【题意】

    【思路】

    • 因为题目保证一定有解,所有优化时间复杂度的关键就是不要重复染色,所以我们可以用并查集维护区间,把确定的点的父亲节点设为下一个点,这样访问过的点的根节点都是没访问过的点。
    • 与上一题是同样的思路,用并查集路径压缩,
    • 要求字典序最小,可以最初给每个字符都赋值'a'
    • 判断字符串最长是多少,最后加''

    【Accepted】

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<string>
     5 #include<cmath>
     6 #include<algorithm>
     7 #include<set>
     8 #include<queue>
     9 using namespace std;
    10 const int N=1e6+3;
    11 const int maxn=2*N;
    12 const int inf=0x3f3f3f3f;
    13 int fa[maxn];
    14 int n,m;
    15 int a[maxn];
    16 char str[maxn];
    17 char ans[maxn];
    18 int find(int x)
    19 {
    20     return fa[x]==x?x:fa[x]=find(fa[x]);
    21 }
    22 
    23 void init()
    24 {
    25     for(int i=0;i<maxn;i++){
    26         fa[i]=i;
    27     }
    28 }
    29 int main()
    30 {
    31     while(~scanf("%d",&n))
    32     {
    33         init();
    34         memset(ans,'a',sizeof(ans));
    35         int mmax=-inf;
    36         for(int i=0;i<n;i++)
    37         {
    38             scanf("%s%d",str,&m);
    39             int len=strlen(str);
    40             int v=-inf;
    41             for(int k=0;k<m;k++)
    42             {
    43                 scanf("%d",&a[k]);
    44                 v=max(v,a[k]);
    45             }
    46             mmax=max(mmax,v+len);
    47             for(int k=0;k<m;k++)
    48             {
    49                 int x=a[k];
    50                 int y=a[k]+len-1;
    51                 while((x=find(x))<=y)
    52                 {
    53                     ans[x]=str[x-a[k]];
    54                     fa[x]=x+1;
    55                 }
    56             }
    57         }
    58         ans[mmax]='';
    59         cout<<ans+1<<endl;
    60 
    61         
    62     }
    63     return 0;
    64 }
    View Code

    或者

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<string>
     5 #include<cmath>
     6 #include<algorithm>
     7 #include<set>
     8 #include<queue>
     9 using namespace std;
    10 const int N=1e6+3;
    11 const int maxn=2*N;
    12 const int inf=0x3f3f3f3f;
    13 int fa[maxn];
    14 int n,m;
    15 int a[maxn];
    16 char str[maxn];
    17 char ans[maxn];
    18 int find(int x)
    19 {
    20     return fa[x]==x?x:fa[x]=find(fa[x]);
    21 }
    22 
    23 void init()
    24 {
    25     for(int i=0;i<maxn;i++){
    26         fa[i]=i;
    27     }
    28 }
    29 int main()
    30 {
    31     while(~scanf("%d",&n))
    32     {
    33         init();
    34         memset(ans,'a',sizeof(ans));
    35         int mmax=-inf;
    36         for(int i=0;i<n;i++)
    37         {
    38             scanf("%s%d",str,&m);
    39             int len=strlen(str);
    40             for(int k=0;k<m;k++)
    41             {
    42                 scanf("%d",&a[k]);
    43             }
    44             mmax=max(mmax,a[m-1]+len);
    45             for(int k=0;k<m;k++)
    46             {
    47                 int x=a[k];
    48                 int y=a[k]+len-1;
    49                 while((y=find(y))!=find(x-1))
    50                 {
    51                     ans[y]=str[y-a[k]];
    52                     fa[y]=fa[y-1];
    53                 }
    54             }
    55         }
    56         ans[mmax]='';
    57         cout<<ans+1<<endl;
    58 
    59         
    60     }
    61     return 0;
    62 }
    View Code

    从右往左或从左往右合并都一样。

    一开始在数据8上T了好几回,原来并查集的find一开始没注意没有路径压缩..........

  • 相关阅读:
    volley框架使用
    Insert Interval
    candy(贪心)
    Best Time to Buy and Sell Stock
    Best Time to Buy and Sell Stock III
    distinct subsequences
    edit distance(编辑距离,两个字符串之间相似性的问题)
    trapping rain water
    word break II(单词切分)
    sudoku solver(数独)
  • 原文地址:https://www.cnblogs.com/itcsl/p/7187045.html
Copyright © 2011-2022 走看看