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 (1≤ai≤1091≤ai≤109).

For some strange reason, you must choose some integer ll and rr (1≤l≤r≤n1≤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.

T≤104,∑n≤106T≤104,∑n≤106OutputFor 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;
}
时间: 2024-11-08 22:48:21

HDU 5328 Problem Killer(尺取法)的相关文章

hdu 5328 Problem Killer(杭电多校赛第四场)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5328 题目大意:找到连续的最长的等差数列or等比数列. 解题思路:1.等差等比的性质有很多.其中比较重要的一个就是解题关键:如a[i-2],a[i-1],a[i],a[i+1]这个序列.a[i-2],a[i-1],a[i]是等差数列,a[i-1],a[i],a[i+1]也是等差数列.那么a[i-2],a[i-1],a[i],a[i+1]就是等差数列.  2. 等比数列也是一样的~~只要根据这个性质就

HDU 5328 Problem Killer(水题)

题意:给一个序列,要找一个等差或等比的连续子序列,求其最长的长度. 思路:扫两遍,判断等差或等比即可.从左往右扫,维护一个滑动窗口,考虑新加进来的数,如果满足了要求,则更新长度,否则只留最后两个数字,其他删掉,接着继续考虑下一个数字.等比也是如此,只是要注意精度的问题. 别人的代码: 1 #include <bits/stdc++.h> 2 using namespace std; 3 const int MAX = 1e6+2; 4 int arr[MAX]; 5 6 int main(vo

HDU 5328 Problem Killer

题意:给一段序列,求连续的子序列中最长的等差数列或者等比数列的长度. 解法:O(n)的扫两遍一次判等差一次判等比就好了. 代码: #include<stdio.h> #include<iostream> #include<algorithm> #include<string> #include<string.h> #include<math.h> #include<limits.h> #include<time.h&

POJ 3320 Jessica&#39;s Reading Problem (尺取法)

Jessica's a very lovely girl wooed by lots of boys. Recently she has a problem. The final exam is coming, yet she has spent little time on it. If she wants to pass it, she has to master all ideas included in a very thick text book. The author of that

poj 3320 Jessica&#39;s Reading Problem(尺取法)

Description Jessica's a very lovely girl wooed by lots of boys. Recently she has a problem. The final exam is coming, yet she has spent little time on it. If she wants to pass it, she has to master all ideas included in a very thick text book. The au

POJ - 3320 Jessica&#39;s Reading Problem(尺取法+STL)

题目链接:http://poj.org/problem?id=3320 题意:一本n页的书(有很多重复的页),要求连续最少页数把这本书每种页都包括进去,求出最少页数. 例如1 8 8 8 1 就1和8两种页,第一次1 8连续两页就把每种页都包括进去了. 尺取法:顾名思义就是一段一段的取.一开始一直往后取,符合条件,然后进行前面减少操作,不符合条件再往后取. 如此重复,得到最优的解.这道题目给出的页的标记好像有特别大的,直接用数组的话会爆炸. 试过用vector,但是对vector的操作太麻烦了.

题解报告:poj 3320 Jessica&#39;s Reading Problem(尺取法)

Description Jessica's a very lovely girl wooed by lots of boys. Recently she has a problem. The final exam is coming, yet she has spent little time on it. If she wants to pass it, she has to master all ideas included in a very thick text book. The au

HDU 6103 Kirinriki(尺取法)

http://acm.hdu.edu.cn/showproblem.php?pid=6103 题意: 给出一个字符串,在其中找两串互不重叠的子串,计算它们之间的dis值,要求dis值小于等于m,求能选的子串的最大长度. 思路: 由于这两个子串是互不重叠的,那么这两个子串之间的间隔可以是奇数也可以是偶数,针对这两种情况我们枚举中心点,然后尺取法处理,具体看代码就懂了. 1 #include<iostream> 2 #include<algorithm> 3 #include<c

HDU 5328(Problem Killer-暴力)

Problem Killer Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 1535    Accepted Submission(s): 576 Problem Description You are a "Problem Killer", you want to solve many problems. Now you