HDU 5328 Problem Killer(尺取法)

You are a "Problem Killer", you want to solve many problems.
Now you have nn problems, the ii-th problem's difficulty is represented by an integer aiai (1ai1091≤ai≤109).
For some strange reason, you must choose some integer ll and rr (1lrn1≤l≤r≤n), and solve the problems between the ll-th and the rr-th, and these problems' difficulties must form an AP (Arithmetic Progression) or a GP (Geometric Progression).
So how many problems can you solve at most?

You can find the definitions of AP and GP by the following links:
https://en.wikipedia.org/wiki/Arithmetic_progression
https://en.wikipedia.org/wiki/Geometric_progression

InputThe first line contains a single integer TT, indicating the number of cases.
For each test case, the first line contains a single integer nn, the second line contains nn integers a1,a2,,ana1,a2,⋯,an.

T104,n106T≤104,∑n≤106
OutputFor each test case, output one line with a single integer, representing the answer.Sample Input

2
5
1 2 3 4 6
10
1 1 1 1 1 1 2 3 4 5

Sample Output

4
6

分析:分别对等差数列和等比数列进行尺取,找其中的最大值
代码如下:
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
typedef long long ll;
const int MAXN=1e6+10;
ll a[MAXN];
ll Q[MAXN];
ll t,n,l,r,mid,maxx;
void check1()
{
    ll l=0,r=0,k,num;
    Q[r++]=a[0];
    Q[r++]=a[1];
    num=0;
    while(1)
    {
        while(r<n&&a[r]-Q[r-1]==Q[r-1]-Q[r-2])
        {
            Q[r]=a[r];
            r++;
        }
        num=max(r-l,num);
        if(r==n)break;
        Q[r]=a[r];
        r++;
        l=r-2;
    }
    maxx=max(num,maxx);
}

void check2()
{
    ll l=0,r=0,k,num;
    Q[r++]=a[0];
    Q[r++]=a[1];
    num=0;
    while(1)
    {
        while(r<n&&a[r]*Q[r-2]==Q[r-1]*Q[r-1])
        {
            Q[r]=a[r];
            r++;
        }
        num=max(r-l,num);
        if(r==n)break;
        Q[r]=a[r];
        r++;
        l=r-2;
    }
      maxx=max(maxx,num);
}
int main()
{
    scanf("%d",&t);
    while(t--)
    {
      maxx=0;
      scanf("%d",&n);
      for(int i=0;i<n;i++)
      scanf("%d",&a[i]);
      if(n<=2)
      {
          printf("%d\n",n);
          continue;
      }
   /*   l=2;
      r=n;
       while(l+1<r)
       {
          mid=(l+r)/2;
          if(check1(mid)||check2(mid))
           l=mid;
          else
           r=mid;
       }*/
       check1();
       check2();
       printf("%lld\n",maxx);
    }
    return 0;
}

 

posted @ 2017-12-23 20:14  hinata_hajime  阅读(164)  评论(0编辑  收藏  举报