Every day a new programming problem is published on Codehorses. Thus, n problems will be published in the following n days: the difficulty of the i-th problem is ai.
Polycarp wants to choose exactly three days i, j and k (i < j < k) so that the difference of difficulties on the day j and the day i is equal to the difference of difficulties on the day k and day j. In other words,Polycarp wants equality aj − ai = ak − aj to be true.
Determine the number of possible ways for Polycarp to choose the three days in the desired way.
Polycarp wants to choose exactly three days i, j and k (i < j < k) so that the difference of difficulties on the day j and the day i is equal to the difference of difficulties on the day k and day j. In other words,Polycarp wants equality aj − ai = ak − aj to be true.
Determine the number of possible ways for Polycarp to choose the three days in the desired way.
输入
The first line contains an integer t — the number of test cases in the input (1 ≤ t ≤ 10). Then t test case descriptions follow.
The first line of a test case contains an integer n — the number of the days (3 ≤ n ≤ 2000).
The second line of the test case contains n integers a1, a2, ... , an, where ai is the difficulty of the problem on the i-th day (1 ≤ ai ≤ 109).
The first line of a test case contains an integer n — the number of the days (3 ≤ n ≤ 2000).
The second line of the test case contains n integers a1, a2, ... , an, where ai is the difficulty of the problem on the i-th day (1 ≤ ai ≤ 109).
输出
Output t integers — the answers for each of the test cases in the input, in the order they are given. The answer to a test case is the number of triples of indices i, j, and k such that 1 ≤ i < j < k ≤ n and
ak − aj = aj − ai.
ak − aj = aj − ai.
样例输入 Copy
4
5
1 2 1 2 1
3
30 20 10
5
1 2 2 3 4
9
3 1 4 1 5 9 2 6 5
样例输出 Copy
1 1 4 5
题目的意思就是让你找一个三元组i,j,k,使得ak − aj = aj − ai.暴力肯定要超时,显然要对式子变形。
1.一开始是做的时候我们做的时候就是变成2*a[j]=a[k]+a[i]就是枚举a[k]和a[i]。用一个前缀和的思想预处理出来a[k]到a[i]的
中a[j]的个数
#include<bits/stdc++.h> using namespace std; typedef long long ll; unordered_map<ll,ll> mp; inline ll read(){ ll x=0; bool f=0; char ch=getchar(); while (ch<'0'||'9'<ch) f|=ch=='-', ch=getchar(); while ('0'<=ch && ch<='9') x=x*10+ch-'0',ch=getchar(); return f?-x:x; } ll a[2010],f[2010][2010]; int main() { ll t; t=read(); while(t--) { memset(a,0,sizeof a); int n; n=read(); int s = 0; for(int i=1;i<=n;i++) { a[i]=read(); if(!mp[a[i]]) mp[a[i]]=++s; } memset(f,0,sizeof f); for(int i=1;i<=s;i++) { for(int j=1;j<=n;j++) { //f[i][j]表示前j项中有多少个i if(mp[a[j]]==i) f[i][j]=f[i][j-1]+1; else f[i][j]=f[i][j-1]; } } ll ans=0; for(int i=1;i<=n-2;i++) { for(int k=i+2;k<=n;k++) { ll tmp=a[i]+a[k]; if(tmp%2!=0) continue; ll val=tmp/2; ll idx=mp[val]; ll num=f[idx][k-1]-f[idx][i]; ans+=num; } } printf("%lld ",ans); mp.clear(); } return 0; }
2.正解就是让a[i]=2*a[j]-a[k],就一个map就解决了,太妙了
#pragma GCC optimize(1) #pragma GCC optimize(2) #pragma GCC optimize(3,"Ofast","inline") #include<cstring> #include<map> #include<cstdio> #include<iostream> #include<queue> #include<algorithm> using namespace std; typedef long long ll; template <typename Tp> void read(Tp &x){//read(n); x=0;char ch=1;int fh; while(ch!='-'&&(ch>'9'||ch<'0')){ ch=getchar(); } if(ch=='-'){ fh=-1;ch=getchar(); }else fh=1; while(ch>='0'&&ch<='9'){ x=(x<<1)+(x<<3)+ch-'0';ch=getchar(); } x*=fh; } inline char read1()//字符串读入挂 { register char ch=getchar(); while(ch<'A'||ch>'M')ch=getchar(); return ch; } const int maxn=1e6+100; const int mod=1000000007; int a[maxn]; map<int,int>mp; int main() { ll t; read(t); while(t--){ mp.clear(); int n; cin>>n; for(int i=1;i<=n;i++){ cin>>a[i]; } mp[a[1]]=1; int ans=0; for(int j=2;j<=n;j++){ for(int k=j+1;k<=n;k++){ int temp=2*a[j]-a[k]; if(temp<0||mp[temp]==0){ continue; } ans+=mp[temp]; } mp[a[j]]++;//这样就能找出j之前的a[i]的个数 } cout<<ans<<endl; } return 0; }