2019杭电0场ccpc江西省赛(重现)Wave

Avin is studying series. A series is called “wave” if the following conditions are satisfied:

  1. It contains at least two elements;
  2. All elements at odd positions are the same;
  3. All elements at even positions are the same;
  4. Elements at odd positions are NOT the same as the elements at even positions.
    You are given a series with length n. Avin asks you to find the longest “wave” subseries. A subseries is a subsequence of a series.
    InputThe first line contains two numbers n, c (1 ≤ n ≤ 100, 000, 1 ≤ c ≤ 100). The second line contains n integers whose range is [1, c], which represents the series. It is guaranteed that there is always a “wave” subseries.
    OutputPrint the length of the longest “wave” subseries.

Sample Input
5 3
1 2 1 3 2
Sample Output
4
题意:
题目给你一个序列,找一个波的最大长度,波定义为:
1)它包含至少两个元素;
2)奇数位置的所有元素都是相同的;
3)偶数位置的所有元素都是相同的;
4)奇数位置的元素与偶数位置的元素不同
这个题比赛时亨亨写了一发优化暴力直接a了,后来听学长讲解,第一次听到序列自动机这个高bi格的东西,即一个二维的数组next [i][j],表示在数i的第j个的位置,然后枚举奇偶两个位置,保存最大值;
预处理:

for(int i=1;i<=n;i++)
    {
        ll k;
        scanf("%lld",&k);
        a[k].push_back(i);			//将输入的每个数的位置保存下来,之后就可以遍历奇数和偶数的位置;
    }

遍历

for(int i=1;i<=c;i++)
    {
        for(int j=1;j<=c;j++)
        {
            if(i==j) continue;
            ll num=0;
            ll s1=a[i].size(),s2=a[j].size();
            //printf("%d: %lld %d: %lld\n",i,s1,j,s2);
            ll k=0,p=0,q=0;
            while(1)
            {
                while(p<s1&&k>a[i][p])                     //遍历奇数
                //用k记录上一个遍历的位置,下一个位置要>K才行;
                    p++;
                if(p==s1)
                    break;
                num++;
                k=a[i][p];
                while(q<s2&&k>a[j][q])                      //遍历偶数
                    q++;
                if(q==s2)
                    break;
                k=a[j][q];
                num++;
            }
            ans=max(ans,num);
            //printf("%lld\n",ans);
        }
    }

代码

#include<bits/stdc++.h>
#include<map>
#define ll long long
using namespace std;
const int maxn=1e5+7;
const int INF=1e9;
vector<ll >a[105];
int main()
{
    ll n,c;
    scanf("%lld%lld",&n,&c);
    for(int i=1;i<=n;i++)
    {
        ll k;
        scanf("%lld",&k);
        a[k].push_back(i);
    }
    /*for(int i=1;i<=c;i++)
    {
        printf("%d: ",i);
        for(int j=0;j<a[i].size();j++)
            printf("%lld ",a[i][j]);
        printf("\n");
    }*/
    ll ans=0;
    for(int i=1;i<=c;i++)
    {
        for(int j=1;j<=c;j++)
        {
            if(i==j) continue;
            ll num=0;
            ll s1=a[i].size(),s2=a[j].size();
            //printf("%d: %lld %d: %lld\n",i,s1,j,s2);
            ll k=0,p=0,q=0;
            while(1)
            {
                while(p<s1&&k>a[i][p])                     //奇数
                    p++;
                if(p==s1)
                    break;
                num++;
                k=a[i][p];
                while(q<s2&&k>a[j][q])                      //偶数
                    q++;
                if(q==s2)
                    break;
                k=a[j][q];
                num++;
            }
            ans=max(ans,num);
            //printf("%lld\n",ans);
        }
    }
    printf("%lld\n",ans);
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值