题目描述
给出一串数以及一个数字C,要求计算出所有A-B=C的数对的个数。
(不同位置的数字一样的数对算不同的数对)
输入格式
第一行包括2个非负整数N和C,中间用空格隔开。
第二行有N个整数,中间用空格隔开,作为要求处理的那串数。
输出格式
输出一行,表示该串数中包含的所有满足A-B=C的数对的个数。
样例输入
4 1
1 1 2 3
样例输出
3
数据范围
对于90%的数据,N <= 2000;
对于100%的数据,N <= 200000。
所有输入数据都在int范围内。
思路
用两个优先队列(小根堆 相当于将数据从小到大排一遍序)
因为差是固定的 随意减数和被减数在两个队列中相对前后顺序是一样的
遍历一遍即可
代码(C++)
#include <cstdio>
#include <queue>
using namespace std;
int n,c,m,k,num,w; char x; long long a=0,b=0,ans=0;
priority_queue <int,vector<int>,greater<int> > p,q;
inline int read();
int main()
{
n=read(); c=read();
for(int i=1;i<=n;++i)
m=read(),p.push(m),q.push(m);
while(!p.empty()&&!q.empty())
{
k=p.top();
a=0; b=0;
while(p.top()==k)
++a,p.pop();
while(!q.empty()&&q.top()<c+k)
q.pop();
while(!q.empty()&&q.top()==c+k)
++b,q.pop();
ans+=a*b;
}
printf("%lld",ans);
return 0;
}
inline int read()
{
num=0; x=getchar();
while(!((x>=48&&x<=57)||x==45))
x=getchar();
if(x==45) w=-1,x=getchar();
else w=1;
while(x>=48&&x<=57)
num=num*10+x-48,x=getchar();
return num*w;
}