P1102 A-B 数对
题目描述
给出一串正整数数列以及一个正整数 CCC,要求计算出所有满足 A−B=CA - B = CA−B=C 的数对的个数(不同位置的数字一样的数对算不同的数对)。
输入格式
输入共两行。
第一行,两个正整数 N,CN,CN,C。
第二行,第 iii 个数为 aia_iai,数字之间用一个空格隔开,共 NNN 个正整数,作为要求处理的那串数。
输出格式
一行,表示该串正整数中包含的满足 A−B=CA - B = CA−B=C 的数对的个数。
输入输出样例 #1
输入 #1
4 1
1 1 2 3
输出 #1
3
说明/提示
对于 100%100\%100% 的数据,1≤N≤2×1051 \leq N \leq 2 \times 10^51≤N≤2×105,0≤ai<2300 \leq a_i <2^{30}0≤ai<230,1≤C<2301 \leq C < 2^{30}1≤C<230。
暴力做法
先排序,然后再挨个遍历即可。
得分 76pts76pts76pts,时间超限。
cpp
#include<bits/stdc++.h>
#define int long long
using namespace std;
bool cmp(int a,int b) {return a<b;}
signed main() {
ios::sync_with_stdio(false);
cin.tie(0);
int n,c,answer=0;
cin>>n>>c;
int a[n];
for(int i=0;i<n;i++)
cin>>a[i];
sort(a,a+n,cmp);
for(int i=n-1;i>=0;i--) {
for(int j=i-1;j>=0;j--)
if(a[i]-a[j]==c)
++answer;
}
cout<<answer<<endl;
return 0;
}
二分做法
lower_bound 和 upper_bound 的用法:
lower_bound:第一个 ≥\geq≥ val的位置;
upper_bound:第一个 >\gt> val的位置。
查询某个值出现的次数:auto lo = lower_bound(a.begin(), a.end(), target);
auto hi = upper_bound(a.begin(), a.end(), target);
int count = hi - lo; // target 出现的次数
100pts,O(NlogN)100pts,O(N \log N)100pts,O(NlogN):
cpp
#include<bits/stdc++.h>
#define int long long
using namespace std;
bool cmp(int a,int b) {return a<b;}
signed main() {
ios::sync_with_stdio(false);
cin.tie(0);
int n,c,answer=0;
cin>>n>>c;
vector<int> a(n);
for(int i=0;i<n;i++)
cin>>a[i];
sort(a.begin(),a.end(),cmp);
for(int i=n-1;i>=0;i--) {
if(a[i]<c) break;
int val=a[i]-c;
auto l=lower_bound(a.begin(),a.end(),val);
auto r=upper_bound(a.begin(),a.end(),val);
answer+=(r-l);
}
cout<<answer<<endl;
return 0;
}
双指针做法
100pts,O(NlogN)100pts,O(N \log N)100pts,O(NlogN):
思路与二分做法相同。
cpp
#include<bits/stdc++.h>
#define int long long
using namespace std;
signed main() {
ios::sync_with_stdio(false);
cin.tie(0);
int n, c, answer = 0;
cin >> n >> c;
vector<int> a(n);
for (int i = 0; i < n; i++)
cin >> a[i];
sort(a.begin(), a.end());
int l = 0, r = 0;
for (int i = 0; i < n; i++) {
int target = a[i] - c; while (l < n && a[l] < target) l++;
while (r < n && a[r] <= target) r++;
answer += r - l;
}
cout << answer << endl;
return 0;
}
