A-B 数对
题目描述
给出一串正整数数列以及一个正整数 \(C\),要求计算出所有满足 \(A - B = C\) 的数对的个数(不同位置的数字一样的数对算不同的数对)。
输入格式
输入共两行。
第一行,两个正整数 \(N,C\)。
第二行,\(N\) 个正整数,作为要求处理的那串数。
输出格式
一行,表示该串正整数中包含的满足 \(A - B = C\) 的数对的个数。
样例 #1
样例输入 #1
4 1
1 1 2 3
样例输出 #1
3
提示
对于 \(75\%\) 的数据,\(1 \leq N \leq 2000\)。
对于 \(100\%\) 的数据,\(1 \leq N \leq 2 \times 10^5\),\(0 \leq a_i <2^{30}\),\(1 \leq C < 2^{30}\)。
分析
- 已知 \(C\),可以使用双重循环枚举 \(A,B\),复杂度 \(O(n^2)\),这样会超时.
- 那么这样的问题,考虑标记某个数出现次数,可以优化到 \(O(n)\).
- 也可以使用下标距离的方式,对元素排序,利用下标差值确定元素个数,复杂度 \(O(nlogn)\).
- 注意开 \(long long\),同时由于数据 \(2^30\),需要使用 \(map\) 映射。
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=1e6+10, INF=0x3f3f3f3f;
int a[N],n,A,B,C;
map<LL,LL> mp;
LL ans=0;
void slove1() {
for(int i=1; i<=n; i++) {
for(int j=1; j<=n; j++) {
if(i!=j && a[i]-a[j]==C) {
ans++;
}
}
}
}
void slove2() {
for(int i=1; i<=n; i++) mp[a[i]]++;
for(int i=1; i<=n; i++) {
int A=a[i], B=a[i]-C;
ans += mp[B];
}
}
void slove3() {
sort(a+1, a+1+n);
for(int i=1; i<=n; i++) {
int A=a[i], B=a[i]-C;
int l=lower_bound(a+1, a+1+n, B)-a;
int r=upper_bound(a+1, a+1+n, B)-a;
ans += r-l;
}
}
int main() {
// freopen("data.in", "r", stdin);
cin>>n>>C;
for(int i=1; i<=n; i++) cin>>a[i];
slove2();
cout<<ans<<endl;
return 0;
}
标签:正整数,P1102,int,数对,样例,long,leq
From: https://www.cnblogs.com/hellohebin/p/16772534.html