洛谷题单【算法1-6】二分查找与二分答案——P2249 A-B 数对

119 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第22天,点击查看活动详情

A-B 数对

题目描述

出题是一件痛苦的事情!

相同的题目看多了也会有审美疲劳,于是我舍弃了大家所熟悉的 A+B Problem,改用 A-B 了哈哈!

好吧,题目是这样的:给出一串数以及一个数字 CC,要求计算出所有 AB=CA - B = C 的数对的个数(不同位置的数字一样的数对算不同的数对)。

输入格式

输入共两行。

第一行,两个整数 N,CN, C

第二行,NN 个整数,作为要求处理的那串数。

输出格式

一行,表示该串数中包含的满足 AB=CA - B = C 的数对的个数。

样例 #1

样例输入 #1

4 1
1 1 2 3

样例输出 #1

3

提示

对于 75%75\% 的数据,1N20001 \leq N \leq 2000

对于 100%100\% 的数据,1N2×1051 \leq N \leq 2 \times 10^5

保证所有输入数据绝对值小于 2302^{30},且 C1C \ge 1

2017/4/29 新添数据两组

思路

一开始想用hash数组,但是数字大小为2e30,开这么大的数组不现实,因为实际输入的个数只有2e5,因此利用map映射,存储每一个数字出现的位置更加合理

然后将问题转化为迭代map容器,求所有键大小差c的pair对的值的乘积,并且将所有可能的乘积加和返回即可。

这里执行过程中出现了MLE,内存超了,网上查询方法后发现可以使用fflush(stdin)清除缓冲区可能是因为数据大小为2e30,缓冲区过大造成的

代码

// P1102 A-B 数对
// map映射

#include <iostream>
#include <map>
using namespace std;
typedef long long ll;
int main(){
    map<ll, ll> m;
    ll n, c;
    cin >> n >> c;
    for(ll i=0; i<n; i++){
        ll temp;
        cin >> temp;
        m[temp]++;
    }
    // fflush(stdin);
    ll cnt = 0;
    for (auto iter = m.begin(); iter!=m.end(); ++iter) {
        if(iter->second)
        cnt += iter->second * m[iter->first+c];
    }
    cout << cnt;
}