题目
题目链接
题意
给n个数和c,求a,b的对数(使得$$a-b=c$$)
思路
-
多种方法可求解
-
二分/哈希/双指针
-
二分做法:将序列从小到大排序(保证单调递增)后,遍历前n-1个数(把每个数当作b,若有$$a-b=c$$,则$$a=b+c$$,找a)
-
若a存在多个,则先找第一个a出现的位置(二分大于等于a的位置),再找小于(x+1)的位置
坑点
-
注意二分的边界问题即可
代码
//二分做法
#include<bits/stdc++.h>
#define endl '\n'
#define int long long
using namespace std;
const int N = 2e5+10;
typedef long long ll;
int num[N];
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
int n,c;
cin>>n>>c;
int ans=0;
//给定差值 枚举b,找a
//b固定时
for(int i=0;i<n;i++)
{
cin>>num[i];
}
sort(num,num+n);
for(int i=0;i<n-1;i++)
{
int x=num[i]+c;
//找x的位置
//找小于x+1的位置
int l=0,r=n-1;
while(l<r)
{
int mid=(l+r)/2;
if(num[mid]>=x)
{
r=mid;
}else{
l=mid+1;
}
}
if(num[l]==x)
{
//cout<<x<<endl;
int a=0,b=n-1;
while(a<b)
{
int mid=(a+b+1)/2;
if(num[mid]<(x+1))
{
a=mid;
}else{
b=mid-1;
}
}
ans+=a-l+1;
//cout<<a-l+1<<endl;
}else{
continue;
}
}
cout<<ans<<endl;
return 0;
}
总结
题目不错,多种做法,熟悉二分的题目