hdu 1711 Number Sequence

http://acm.hdu.edu.cn/showproblem.php?pid=1711 

题意:给两个数字序列,判断第一个是否包含了第二个数列。

 

思路一(正解): 直接kmp;

 

思路二(YY): 求出第一个序列的前缀和,在第一个序列中取和第二个序列等长的子序列,如果这个子序列的和与第二个序列的和一样,才进行匹配算法。这个算法可以过不了一些特殊的数据。但在很短的时间内过了。

View Code
#include<stdio.h>
#include<string.h>
long long as[1000005],bs[10005],cs[1000005];
int check(long long x,long long m)
{
    long long i;
    for(i = 1; i <= m; ++ i,++x) if(as[x]!=bs[i])return 0;
    return 1;
}
int main()
{
    long long i,j,k,t,n,m;
    long long suma,sumb;
    scanf("%I64d",&t);
    while(t--)
    {
        scanf("%I64d%I64d",&n,&m);
        suma = sumb = 0;
        for(i = 1; i <= n; ++ i){ scanf("%I64d",&k); suma += k; as[i] = k; cs[i] = suma; }
        for(i = 1; i <= m; ++ i){ scanf("%I64d",&k); sumb += k; bs[i] = k; }
        for(i = 0; i + m <= n; ++ i) if(((cs[i+m]-cs[i])==sumb)&&check(i+1,m))break;
        if(i+m<=n) printf("%I64d\n",i+1);
        else puts("-1");
    }return 0;
}

思路三:后缀数组直接应用。

下面代码 过不了这组数据的:
5 3 

1 2 3 4 5

3 4 5

但却ac了,不解,求解中~~~

View Code
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
const int maxn = 2010000;
int wn[maxn],wa[maxn],wb[maxn],wv[maxn],as[maxn],sa[maxn],rank[maxn],height[maxn];

int Max(int x,int y){return x>y?x:y;}
int Min(int x,int y){return x>y?y:x;}
int cmp(int *r,int a,int b,int l){ return r[a]==r[b]&&r[a+l]==r[b+l]; }
void da(int *r,int *sa,int n,int m)
{
    int i,j,p,*x=wa,*y=wb,*t;
    for(i = 0; i < m; ++ i) wn[i] = 0;
    for(i = 0; i < n; ++ i) wn[x[i]=r[i]]++;
    for(i = 1; i < m; ++ i) wn[i] += wn[i-1];
    for(i = n - 1; i >= 0; --i) sa[--wn[x[i]]] = i;
    for(p = 1,j = 1; p < n; j *= 2,m = p)
    {
        for(p = 0,i = n-j; i < n; ++ i) y[p++] =i;
        for(i = 0; i < n; ++ i) if(sa[i]>=j) y[p++] = sa[i] - j;
        for(i = 0; i < m; ++ i) wn[i] = 0;
        for(i = 0; i < n; ++ i) wn[wv[i]=x[y[i]]]++;
        for(i = 1; i < m; ++ i) wn[i] += wn[i-1];
        for(i = n - 1; i >= 0; --i) sa[--wn[wv[i]]] = y[i];
        for(t = x,x = y,y = t,x[sa[0]] = 0,p=1,i=1; i<n; ++i)
            x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++;
    }
}
void calheight(int *r,int *sa,int n)
{
    int i,j,k = 0;
    for(i = 1; i <= n; ++ i){ rank[sa[i]] = i; height[i] = 0;}
    for(i = 0; i < n; height[rank[i++]]=k)
        for(k?k--:0,j=sa[rank[i]-1]; r[i+k]==r[j+k];++k);
}
int main()
{
    int i,j,k,n,m,cnt,L,t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d %d",&n,&m);
        k = 0;
        for(i = 0; i < n; ++ i){ scanf("%d",as+i); k = Max(k,abs(as[i])); }
        for(i ++; i <= n + m; ++ i){ scanf("%d",as+i); k = Max(k,abs(as[i])); }
        ++k;
        as[n] = k;
        for(i = 0; i <= n + m; ++ i) as[i] += k;
        as[i] = 0;
        da(as,sa,i+1,k*2+1);
        calheight(as,sa,n+m);
        for(i = 1; i <= n + m; ++ i)
             if((height[i]==m)&&(sa[i]==n+1||sa[i-1]==n+1))break;
        if(i>n+m)puts("-1");
        else if(sa[i]==n+1)printf("%d\n",sa[i-1]+1);
        else printf("%d\n",sa[i]+1);
    }return 0;
}

posted on 2012-06-07 15:49  aigoruan  阅读(190)  评论(0)    收藏  举报

导航