Gym - 102411M

题目链接:https://vjudge.net/problem/2891711/origin

问题描述

每天都有一个新的编程问题发布在Codehorses上。因此,n个问题将在接下来的n天内发布:第i个问题的难度是ai。

Polycarp想要选择恰好三天的i, j和k (i<j<k),这样第j日和第i日的困难之差就等于第k日和第j日的困难之差。换句话说,Polycarp想要等式aj−ai=ak−aj为真。

确定Polycarp以所需方式选择三天的可能方法的数量。

输入

第一行包含一个整数t—输入的测试用例的数量(1≤t≤10)。然后t测试用例描述如下。

测试用例的第一行包含一个整数n——天数(3≤n≤2000)。

测试用例的第二行包含n个整数a1,a2,…,an,其中ai为第i天的问题难度(1≤ai≤109)。

输出

输出t整数——按照输入中给出的测试用例顺序给出答案。每个测试用例的答案是满足要求的对应三元组i,j,k(1i<j<kn)的数量,使得akaj=ajai.

样例输入

样例输出

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


1

1

4

5

试题解析:题目意思一目了然:就是先输入一个t表示测试用例的数量,然后输入一个n表示天数,下一行跟着长度为n的数组a表示第i天的题目难度a[i]。

我们要找出这样的i,j,k使得前后两两的差值相等,输出这种三元组有多少种。

我们首先直接想到的方法就是直接判断前后差值是否相等,一个一个找,可是这样得三个循环(一个列举i,一个列举j,一个列举k,1i<j<kn),这么处理显然不太合适。然后我们就能想到可以转换一下思路:那就是如果三个数a[i],a[j],a[k]前后差值相等的话,那么2*a[j]=a[i]+a[k],a[i]=2*a[j]-a[k],我们可以利用这个性质,把问题转换为判断2*a[j]-a[i]的差值是否在给定的数组当中出现即可,是则计数器+1.。然后我们很自然而然的想到map这个数据结构,一个pair,first放数组元素,second统计出现次数。这里使用的循环可以体现出i,j,k的前后关系(所以用unorder_map,map会超时,加之我们只要统计次数)。

程序清单:

//Gym    102411M 
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
unordered_map<ll,ll> mp;
ll a[2005];
int main()
{
    ll T;
    scanf("%lld",&T);
    while(T--){
        mp.clear();
        ll n;
        scanf("%lld",&n);
        for(ll i=1;i<=n;i++) scanf("%lld",&a[i]);
        ll ans=0;
        for(ll i=1;i<=n;i++){
            for(int j=i+1;j<=n;j++){
                ans+=mp[a[i]*2-a[j]];
            }
            mp[a[i]]++;
        }
        printf("%lld\n",ans);
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/Mingusu/p/11980051.html