2015暑假多校联合---Problem Killer(暴力)
Problem Description
You are a "Problem Killer", you want to solve many problems.
Now you have n problems, the i-th problem's difficulty is represented by an integer ai (1≤ai≤109).
For some strange reason, you must choose some integer l and r (1≤l≤r≤n), and solve the problems between the l-th and the r-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
Now you have n problems, the i-th problem's difficulty is represented by an integer ai (1≤ai≤109).
For some strange reason, you must choose some integer l and r (1≤l≤r≤n), and solve the problems between the l-th and the r-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
Input
The first line contains a single integer T, indicating the number of cases.
For each test case, the first line contains a single integer n, the second line contains n integers a1,a2,⋯,an.
T≤104,∑n≤106
For each test case, the first line contains a single integer n, the second line contains n integers a1,a2,⋯,an.
T≤104,∑n≤106
Output
For 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
题意:输入n个数,求其中最长的区间的长度(区间满足等差数列或者等比数列);
思路:两重循环暴力从每个数开始找,但是这样会超时,可以优化一下,记录从当前数开始的等差数列最远的位置,下次从上次记录的最远的位置开始找,这样复杂度会下降很多;
我发现了一个很有意思的事情,我开始写的程序超时了,后来我删掉了一些东西AC了,但我感觉有bug,于是我想了组数据n=5 5个数4 ,8 ,12 , 18 , 27 后面4个数满足等比数列,最长区间应该是4,而我的程序输出是3, 同样这组数据n=6 6个数8 ,16 ,24 , 36 , 54 , 81 后面5个数满足等比数列,输出应该是5,而我的程序输出是4。 我想了一下每次从上次记录的最远的位置开始找,有可能记录的位置的前一位也满足等比数列,所以在计算等比数列长度时得计算一下前一位是否满足;
开始的代码如下:
#include <iostream> #include <algorithm> #include <stdio.h> #include <stdlib.h> #include <cmath> #include <cstring> using namespace std; long long a[1000005]; int main() { int T; cin>>T; while(T--) { int n; scanf("%d",&n); for(int i=0;i<n;i++) scanf("%lld",&a[i]); int tmp=0; int t,j; for(int i=0;i<n;i=t) { for(j=i+1;j<n;j++) { if(a[j]!=a[i]+(a[i+1]-a[i])*(j-i)) break; } t=j-1; tmp=max(tmp,j-i); for(j=i+1;j<n;j++) { if(a[j-1]*a[i+1]%a[i]==0&&a[j]==a[j-1]*a[i+1]/a[i]) continue; else break; } tmp=max(tmp,j-i); //cout<<"t: "<<t<<endl; //if(j-1>i) //t=min(t,j-1); if(t==n-1)break; } printf("%d\n",tmp); } return 0; }
后来修改过的代码:
#include <iostream> #include <algorithm> #include <stdio.h> #include <stdlib.h> #include <cmath> #include <cstring> using namespace std; long long a[1000005]; int main() { int T; cin>>T; while(T--) { int n; scanf("%d",&n); for(int i=0;i<n;i++) scanf("%lld",&a[i]); int tmp=0; int t,j; for(int i=0;i<n;i=t) { for(j=i+1;j<n;j++) { if(a[j]!=a[i]+(a[i+1]-a[i])*(j-i)) break; } t=j-1; tmp=max(tmp,j-i); for(j=i+1;j<n;j++) { if(a[j-1]*a[i+1]%a[i]==0&&a[j]==a[j-1]*a[i+1]/a[i]) continue; else break; } int f=0; if(a[i-1]*a[i+1]%a[i]==0&&a[i]==a[i-1]*a[i+1]/a[i]) f=1; tmp=max(tmp,j-i+f); if(t==n-1)break; } printf("%d\n",tmp); } return 0; }