TimusOJ 1395. Pascal vs. C++. Version 1,2

题意:给你n个数,让你找最长的等差数列。

Solution

想了好久,突然想出了一个非常妙的做法。
首先用hash来记录每一个数(下标)。
然后暴力枚举等差数列的第一项和第二项,假设两个数分别为 x , y x,y x,y,判断如果 2 ∗ x − y 2*x-y 2xy存在,就说明这个等差数列已经被找过,就不用管了,如果没有就暴力跳着找,输出的时候再跳一次就好了。

Code

#include<bits/stdc++.h>
#define ll long long
#define gc getchar
#define pc putchar
#define pii pair<int,int>
#define mp make_pair
#define fi first
#define se second
#define rep(i,x,y) for(int i=x;i<=y;i++)
#define dwn(i,x,y) for(int i=x;i>=y;i--)
using namespace std;
template<typename T>inline void qr(T &x){
  x=0;int f=0;char s=gc();
  while(s<'0'||'9'<s)f|=s=='-',s=gc();
  while('0'<=s&&s<='9')x=x*10+s-48,s=gc();
  x=f?-x:x;
}
int cc=0,buf[31];
template<typename T>inline void qw(T x){
  if(x<0)putchar('-'),x=-x;
  do{buf[++cc]=int(x%10);x/=10;}while(x);
  while(cc)pc(buf[cc--]+'0');
}
const int N=1e4+10,mod=501197;
int n,tot,hd[mod],p[N],nxt[N];pii a[N];
void ins(int id){
  int x=a[id].fi%mod;
  for(int i=hd[x];i;i=nxt[i])if(a[p[i]].fi==a[id].fi)return;
  p[++tot]=id,nxt[tot]=hd[x],hd[x]=tot;
}
int query(int num){
  if(num<=0||num>1e9)return 0;
  int x=num%mod;
  for(int i=hd[x];i;i=nxt[i])if(a[p[i]].fi==num)return a[p[i]].se;
  return 0;
}
int main(){
  int tt;qr(tt);
  rep(i,1,tt)qr(a[i].fi),a[i].se=i;
  sort(a+1,a+tt+1);
  rep(i,1,tt)if(a[i].fi!=a[i-1].fi){a[++n]=a[i];ins(n);}
  if(n==1){puts("1\n1");return 0;}
  int ans=0;pii pos;
  rep(i,1,n)
    rep(j,i+1,n)if(!query(2*a[i].fi-a[j].fi)){
      int now=2;tt=a[j].fi-a[i].fi;
      for(int k=a[j].fi+tt;;k+=tt){
        if(query(k))now++;
        else break;
      }
      if(now>ans)ans=now,pos=mp(i,j);
    }
  qw(ans);puts("");
  qw(a[pos.fi].se),pc(' '),qw(a[pos.se].se),pc(' ');
  tt=a[pos.se].fi-a[pos.fi].fi;
  for(int i=a[pos.se].fi+tt;;i+=tt){
    int now=query(i);
    if(!now)break;
    qw(now),pc(' ');
  }
  return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值