Problem J: Arithmetic Sequence
Time Limit: 1 Sec Memory Limit: 128 MB
Submit: 1801 Solved: 306
[Submit][Status][Web Board]
Description
Giving a number sequence A with length n, you should choosing m numbers from A(ignore the order) which can form an arithmetic sequence and make m as large as possible.
Input
There are multiple test cases. In each test case, the first line contains a positive integer n. The second line contains n integers separated by spaces, indicating the number sequence A. All the integers are positive and not more than 2000. The input will end by EOF.
Output
For each test case, output the maximum as the answer in one line.
Sample Input
5
1 3 5 7 10
8
4 2 7 11 3 1 9 5
Sample Output
4
6
HINT
In the first test case, you should choose 1,3,5,7 to form the arithmetic sequence and its length is 4.
In the second test case, you should choose 1,3,5,7,9,11 and the length is 6.
[Submit][Status]
题意:多组数据,每组数据第一行给出N,第二行给出N个数字。在给定数列中找出最长的等差数列的长度。注意公差可能是0
思路:记录所给数据的最值,最大减最小获取最大公差。记录每个数字出现了多少次,用于解决公差为0的情况。接着两层循环,外层枚举给的数据,内层枚举可能的公差即可。
代码
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
#include<math.h>
using namespace std;
const int maxn=2005;
const int INF=9999999;//正无穷
int num[maxn];//接收数列
int flag[maxn];//记录num[i]出现了flag[num[i]]次
int N;//数列数量
int max_num;//数列中最大数字
int min_num;//数列中最小数字
int max_len;//最长等差数列长度
int main()
{
while(~scanf("%d",&N))
{
max_num=-INF;//各种初始化
min_num=INF;
max_len=0;
memset(num,0,sizeof(num));
memset(flag,0,sizeof(flag));
for(int i=0; i<N; i++)
{
scanf("%d",&num[i]);
flag[num[i]]++;//num[i]出现了flag[num[i]]次
max_num=max(max_num,num[i]);//获取最大最小值
min_num=min(min_num,num[i]);
}
for(int i=0; i<N; i++)//遍历数列
{
max_len=max(max_len,flag[num[i]]);//可能出现公差为0
for(int j=1; j<=max_num-min_num; j++)//遍历所有的公差
{
int flag_len=1;//临时记录长度
int temp=num[i];//数列的首个元素
while(1)
{
temp=temp+j;
if(flag[temp]==0||temp>max_num)//temp没有出现过,或者超出数列长度
break;//结束计数
flag_len++;
}
max_len=max(max_len,flag_len);//更新真实长度
}
}
printf("%d\n",max_len);
}
return 0;
}