zoukankan      html  css  js  c++  java
  • C

    题目链接:https://cn.vjudge.net/contest/283743#problem/C

    题目大意:给你n个数组,然后问你是否有多个“相似”且不重叠的子串的长度大于等于5(两个子串相似当且仅当长度相等且每一位的数字差都相等)。

    具体思路:对于相似,我们直接对于当前的输入的和他的上一位相减就可以了,这样差就表示出来了,然后就开始判断时候有相同的子串并且不重叠并且长度>=5就可以了。判断的时候,首先分组,分组的标准是这个组里面的height是不是大于等k,对于每一个组,找出最大的sa差值,然后就判断差值和5的关系就可以了。对于具体的原因,height[i]数组指的是排序之后,排名为i和i-1的最长公共前缀,然后再分组的时候,如果height数组>=k的时候,就直接判断这两个字符串的开头位置就可以了,这个可以通过sa数组实现。

    AC代码:

      1 #include<iostream>
      2 #include<stack>
      3 #include<cstring>
      4 #include<iomanip>
      5 #include<stdio.h>
      6 #include<algorithm>
      7 #include<cmath>
      8 using namespace std;
      9 # define ll long long
     10 # define inf 0x3f3f3f3f
     11 const int maxn = 5e5+100;
     12 int cntA[maxn], cntB[maxn], sa[maxn], tsa[maxn], A[maxn], B[maxn], height[maxn];
     13 int Rank[maxn];
     14 int ch[maxn];
     15 int sto[maxn];
     16 ll n;
     17 //sa[i]代表第i小的后缀位置,Rank[i]代表第i位置的后缀,排名第几小
     18 // height[i]代表排名第i个字符串和第i-1个字符串的相同前缀有多少个
     19 void cal()
     20 {
     21     for(int i = 0; i < 256; i++)
     22         cntA[i] = 0;
     23      //   cout<<1<<endl;
     24    //  cout<<n<<endl;
     25     for(int i = 1; i <= n; i++){
     26             //cout<<ch[i-1]<<endl;
     27         cntA[ch[i-1]]++;
     28     }
     29       //  cout<<1<<endl;
     30     for(int i = 1; i < 256; i++)
     31         cntA[i] += cntA[i-1];
     32     for(int i = n; i; i--)
     33         sa[cntA[ch[i-1]]--] = i;
     34     Rank[sa[1]] = 1;
     35     for(int i = 2; i <= n; i++)
     36     {
     37         Rank[sa[i]] = Rank[sa[i-1]];
     38         if(ch[sa[i]-1] != ch[sa[i-1]-1])
     39             Rank[sa[i]]++;
     40     }
     41     for(int l = 1; Rank[sa[n]] < n; l <<= 1)
     42     {
     43         memset(cntA, 0, sizeof(cntA));
     44         memset(cntB, 0, sizeof(cntB));
     45         for(int i = 1; i <= n; i++)
     46         {
     47             cntA[A[i] = Rank[i]]++;
     48             cntB[B[i] = (i+l <= n)?Rank[i+l]:0]++;
     49         }
     50         for(int i = 1; i <= n; i++)
     51             cntB[i] += cntB[i-1];
     52         for(int i = n; i; i--)
     53             tsa[cntB[B[i]]--] = i;
     54         for(int i = 1; i <= n; i++)
     55             cntA[i] += cntA[i-1];
     56         for(int i = n; i; i--)
     57             sa[cntA[A[tsa[i]]]--] = tsa[i];
     58         Rank[sa[1]]=1;
     59         for(int i = 2; i <= n; i++)
     60         {
     61             Rank[sa[i]] = Rank[sa[i-1]];
     62             if(A[sa[i]] != A[sa[i-1]] || B[sa[i]] != B[sa[i-1]])
     63                 Rank[sa[i]]++;
     64         }
     65     }
     66     for(int i = 1, j = 0; i <= n; i++)
     67     {
     68         if(j)
     69             j--;
     70         while(ch[i+j-1] == ch[sa[Rank[i]-1] + j - 1])
     71             j++;
     72         height[Rank[i]] = j;
     73     }
     74 }
     75 bool judge(int t)
     76 {
     77     int mx=-inf,mm=inf;
     78     for(int i=2; i<=n; i++)
     79     {
     80         if(height[i]>=t)
     81         {
     82             mm=min(mm,min(sa[i],sa[i-1]));
     83             mx=max(mx,max(sa[i],sa[i-1]));
     84             if(mx-mm>t)
     85                 return true;
     86         }
     87         else
     88         {
     89             mm=inf;
     90             mx=-inf;
     91         }
     92     }
     93     return false;
     94 }
     95 int main()
     96 {
     97     //  int n;
     98     while(scanf("%d",&n)&&n)
     99     {
    100         for(int i=0; i<n; i++)
    101         {
    102             scanf("%d",&sto[i]);
    103         }
    104         for(int i=0; i<n; i++)
    105         {
    106             ch[i]=sto[i+1]-sto[i]+90;
    107         }
    108         n--;
    109         cal();
    110         int ans=-1;
    111         int l=0,r=1e8;
    112         while(l<=r)
    113         {
    114             int mid=(l+r)>>1;
    115         //    cout<<l<<" "<<r<<endl;
    116             if(judge(mid))
    117             {
    118                 ans=mid;
    119                 l=mid+1;
    120                 //  cout<<ans<<endl;
    121             }
    122             else
    123             {
    124                 r=mid-1;
    125             }
    126         }
    127         if(ans>=4)
    128             printf("%d
    ",ans+1);
    129         else
    130         {
    131             printf("0
    ");
    132         }
    133     }
    134     return 0;
    135 }
  • 相关阅读:
    config https in nginx(free)
    js hex string to unicode string
    alter character set
    es6
    音乐播放器
    JS模块化-requireJS
    PHP中的封装和继承
    JavaScriptOOP
    mui框架移动开发初体验
    走进AngularJS
  • 原文地址:https://www.cnblogs.com/letlifestop/p/10390159.html
Copyright © 2011-2022 走看看