题目描述
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1056
随机大法
方法很暴力。
随机一个中间项,然后枚举公差,之后左右拓展,能否拓展用hash判。
随机个一定次数即可。
也可以枚举首项,那么可以加玄学优化就是可行性优化。
我比较水枚举了所有首项。
#include<cstdio>
#include<algorithm>
#define fo(i,a,b) for(i=a;i<=b;i++)
using namespace std;
typedef long long ll;
const int maxn=50000+10,maxd=10000000;
struct dong{
int x,wz;
} b[maxn];
int a[maxn],ha[10000000+10];
int i,j,k,l,r,n,m,d,ca,ans,mx,mi,num;
ll t;
bool cmp(dong a,dong b){
return a.x<b.x||a.x==b.x&&a.wz<b.wz;
}
int hash(int x){
int k=x%maxd;
if (!k) k=maxd;
while (ha[k]!=0&&ha[k]!=x) k=k%maxd+1;
return k;
}
int find(int x){
if (ha[hash(x)]==x) return 1;else return 0;
}
int main(){
//freopen("data.txt","r",stdin);
scanf("%d",&n);
mi=1e9;
fo(i,1,n) scanf("%d",&a[i]),mx=max(mx,a[i]),mi=min(mi,a[i]);
sort(a+1,a+n+1);
a[0]=a[1]-1;
l=0;
fo(i,1,n){
if (a[i]==a[i-1]) l++;
else{
num=max(num,l);
l=1;
}
}
ans=199;
num=max(num,l);
if (num>ans) ans=num;
fo(i,1,n) ha[hash(a[i])]=a[i];
/*fo(i,1,n){
b[i].x=a[i];
b[i].wz=i;
}*/
//sort(b+1,b+n+1,cmp);
fo(i,1,n)
fo(j,i+1,n){
d=a[j]-a[i];
//if (d<0) continue;
t=(ll)a[i]+(ll)d*ans;
if (t<mi||t>mx) continue;
k=a[j];l=2;
while (1){
if (!find(k+d)) break;
l++;
k+=d;
}
if (l>ans) ans=l;
num=max(num,l);
}
if (ans<200) printf("No Solution\n");else printf("%d\n",ans);
}