一、算法分析
很经典的做法,把原来的 a j − a i = j − i a_j-a_i=j-i aj−ai=j−i进行移项,变成 a j − j = a i − i a_j-j=a_i-i aj−j=ai−i,从而生成一个新的数组 b i = a i − i b_i=a_i-i bi=ai−i,对于新数组,只需要统计某个数 b i b_i bi之前有多少个和其相等的数即可。
对于这种题目,要求就是要做得快,代码要一气呵成尽可能不要出错,要思考缜密。比如这道题的 b b b数组元素下标就可能小于0,那么就要用到偏移量或者是用map数组。
二、代码及注释
1 #include<iostream>
2 #include<cstring>
3 #include<algorithm>
4 #include<cstdio>
5 #define LL long long
6 using namespace std;
7 const int N=400050;
8 const int base=N/2; //偏移量
9 int s[N];
10 int n;
11 LL res;
12 int main(){
13
14 int T;
15 scanf("%d",&T);
16 while(T--){
17 res=0;
18 memset(s,0,sizeof(s));
19 scanf("%d",&n);
20 for(int i=1;i<=n;i++){
21 int x;
22 scanf("%d",&x);
23 x+=base-i;
24 res+=s[x];
25 s[x]++;
26 }
27 printf("%lld\n",res);
28 }
29
30
31
32 return 0;
33
34 }
(之前写在小号里了,现在大号找回来了,所以再搬回来汇总一下)