题目背景
出题是一件痛苦的事情!
相同的题目看多了也会有审美疲劳,于是我舍弃了大家所熟悉的 A+B Problem,改用 A-B 了哈哈!
题目描述
给出一串正整数数列以及一个正整数 CC,要求计算出所有满足 A - B = CA−B=C 的数对的个数(不同位置的数字一样的数对算不同的数对)。
输入格式
输入共两行。
第一行,两个正整数 N,CN,C。
第二行,NN 个正整数,作为要求处理的那串数。
输出格式
一行,表示该串正整数中包含的满足 A - B = CA−B=C 的数对的个数。
输入输出样例
输入 #1复制
4 1 1 1 2 3输出 #1复制
3说明/提示
对于 75\%75% 的数据,1 \leq N \leq 20001≤N≤2000。
对于 100\%100% 的数据,1 \leq N \leq 2 \times 10^51≤N≤2×105,0 \leq a_i <2^{30}0≤ai<230,1 \leq C < 2^{30}1≤C<230。
2017/4/29 新添数据两组
1.这个题目不能够纯暴力解决。
2.这里我的思路是我们先排序,找到最大的小于A+C的坐标,然后再去循环看B==A+C的数字,然后记录下来,我们每次都需要刷新k的值是为了保证循环少走。
但是代码第二个和第三个测试点TLE了
C代码如下:
#include<stdio.h>
#define N 200020
long long a[N];
int quicksort(int left,int right)
{
if(left>=right) return 0;
int i=left,j=right;
long long t,temp=a[left];
while(i<j)
{
while(i<j&&a[j]>=a[left]) j--;
while(i<j&&a[i]<=a[left]) i++;
if(i<j)
{
t=a[i];a[i]=a[j];a[j]=t;
}
}
a[left]=a[i];
a[i]=temp;
quicksort(left,i-1);
quicksort(i+1,right);
return 0;
}
int main()
{
int n,c,i,j,sum=0,k;
scanf("%d%d",&n,&c);
for(i=0;i<n;i++)
{
scanf("%lld",&a[i]);
}
quicksort(0,n-1);
i=0,j=n-1;
while(a[j]-a[i]>c&&j>i) j--;
while(a[j]-a[i]==c&&j>i)
{
sum++;
j--;
}
k=j+1;
for(i=1,j=k;i<n;i++)
{
while(a[k]-a[i]<c&&k<n) k++;
j=k;
while(a[j]-a[i]==c&&j<n)
{
j++;
sum++;
}
if(k>=n) break;
}
printf("%d\n",sum);
return 0;
}
C++代码如下:
#include<iostream>
#include<bits/stdc++.h>
#include<algorithm>
using namespace std;
const int N=200020;
long long a[N];
bool cmp(long long a,long long b)
{
return a<b;
}
int main()
{
int n,c,i,j,sum=0,k;
scanf("%d%d",&n,&c);
for(i=0;i<n;i++)
{
scanf("%lld",&a[i]);
}
sort(a,a+n,cmp);
k=1;
for(i=0,j=k;i<n;i++)
{
while(a[k]-a[i]<c&&k<n) k++;
j=k;
while(a[j]-a[i]==c&&j<n)
{
j++;
sum++;
}
if(k>=n) break;
}
printf("%d\n",sum);
return 0;
}