P1102 A-B 数对的三种解法
1.
利用map实现速查,优点是代码简洁,缺点是速度慢,内存大
#include<bits/stdc++.h>
using namespace std;
int a[200005]={0};
int main()
{
int n,c;
scanf("%d%d",&n,&c);
map<int,int> maps;
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
maps[a[i]]++;
}
long long ans=0;
for(int i=1;i<=n;i++)
{
ans+=maps[a[i]+c];
}
printf("%lld\n",ans);
return 0;
}
2.
遍历数组,二分查找,总时间复杂度为O(nlogn)
#include<bits/stdc++.h>
using namespace std;
int a[200005]={0};
int main()
{
int n,c;
scanf("%d%d",&n,&c);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
long long ans=0;
sort(a+1,a+n+1);
for(int i=1;i<=n;i++)
{
int x=a[i]+c;
int l=i,r=n+1;
while(l<r-1)
{
int mid=(l+r)/2;
if(a[mid]>=x)r=mid;
else l=mid;
}
int left=r;
l=i,r=n+1;
while(l<r-1)
{
int mid=(l+r)/2;
if(a[mid]<=x)l=mid;
else r=mid;
}
int right=l;
ans+=right-left+1;
//printf("%d %d : %d\n",left,right,ans);
}
printf("%lld\n",ans);
return 0;
}
3.
指针法,时间复杂度O(n),常数项为4,最优
#include<bits/stdc++.h>
using namespace std;
int a[200005]={0};
int main()
{
int n,c;
scanf("%d%d",&n,&c);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
long long ans=0;
sort(a+1,a+n+1);
long long l1=1,r1=1,l2=2,r2=2;
while(l2<=n)
{
while(a[r1]==a[l1])r1++;
while(l2<=n&&a[l2+1]<a[l1]+c)l2++;
r2=l2+1;
while(r2<=n&&a[r2]<=a[l1]+c)r2++;
ans+=(r1-l1)*(r2-l2-1);
//printf("%d:%d , %d:%d %lld\n",l1,r1,l2,r2,ans);
l1=r1;
}
printf("%lld",ans);
return 0;
}

浙公网安备 33010602011771号