多校#4

1001 -> HDU 5327 Olympiad

打表签到题。开场4minFB的程度... 

应该有更优化的方法,为了手速不TLE就行... = =

1002 -> HDU 5328 ZZX and Permutations

AP: 等差序列

GP: 等比序列

尺取法分别求AP和GP的最长序列长度然后求最大值即可。

需要注意的是等比时最好用比例相等的方法而不要用除法,因为像如[9 6 4]这个样例会产生精度问题,如果用9*4==6*6就不会又问题啦。当然随之产生的问题是相乘的话可能造成int溢出,所以需要long long存a数组。

当无法构成三个元素的AP、GP序列时也要输出1或2;

#include<cstdio>
#include<cstring>
#include<iostream>
#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn = 1000010;
ll a[maxn];
int n;

int AP()
{
    int ret = 2;

    int t1, t2, t3, s;
    s = t1 = 0;
    t2 = 1;
    t3 = 2;
    while(1)
    {
        while(t3 < n && a[t3]-a[t2] == a[t2]-a[t1])
        {
            t1++, t2++, t3++;
        }
        if(t3 >= n)
        {
            ret = max(ret, t3-s);
            break;
        }
        ret = max(ret, t3-s);
        s = t2;
        t1++; t2++; t3++;
    }
    return ret;
}

int GP() //这里直接复制AP()改一点条件即可
{
    int ret = 2;
    int t1, t2, t3, s;
    s = t1 = 0;
    t2 = 1;
    t3 = 2;
    while(1)
    {
        //cout << a[t2] << " " << a[t3] << " " << a[t1] << endl;
        while(t3 < n && a[t2]*a[t2] == a[t3]*a[t1])
        {
            t1++, t2++, t3++;
        }
        if(t3 >= n)
        {
            ret = max(ret, t3-s);
            break;
        }
        ret = max(ret, t3-s);
        s = t2;
        t1++; t2++; t3++;
    }
    return ret;
}

int main()
{
    int T; scanf("%d", &T);
    while(T--)
    {
        scanf("%d", &n);
        for(int i = 0; i < n; i++) scanf("%lld", &a[i]);
        if(n == 1 || n == 2)
        {
            cout << n << endl;
            continue;
        }
        int ap, gp;
        ap = AP();
        gp = GP();
        cout << max(ap, gp) << endl;
    }

    return 0;

}

待续...

原文地址:https://www.cnblogs.com/LLGemini/p/4690985.html