题目描述
出题是一件痛苦的事情!
题目看多了也有审美疲劳,于是我舍弃了大家所熟悉的A+BA+B ProblemProblem,改用A-BA−B了哈哈!
好吧,题目是这样的:给出一串数以及一个数字CC,要求计算出所有A-B=C的数对的个数。(不同位置的数字一样的数对算不同的数对)
输入输出格式
输入格式:
第一行包括22个非负整数NN和CC,中间用空格隔开。
第二行有NN个整数,中间用空格隔开,作为要求处理的那串数。
输出格式:
输出一行,表示该串数中包含的所有满足A-B=CA−B=C的数对的个数。
输入输出样例
输入样例#1:
4 1
1 1 2 3
输出样例#1:
3
说明
对于73%的数据,N ≤ 2000;
对于100%的数据,N ≤200000。
所有输入数据都在longint范围内。
.
.
.
.
.
.
分析
我用了哈希来做,数组开得够大
注意:所有输入数据都在longint范围内!
这说明int可能会爆,并且,它可能会有负数
所以哈希的做法要注意一下
.
.
.
.
.
程序:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
long long mo=1555553;
long long h[1555553][2],a[1555553];
long long tj=0,ans=0;
long long abs(long long x)
{
return x<0?-x:x;
}
int find(int x)
{
long long w=abs(x)%mo,i=0;
while (i<mo&&h[(w+i)%mo][0]!=-1&&h[(w+i)%mo][0]!=x) i++;
if (h[(w+i)%mo][0]==x) return (w+i)%mo;
}
inline int read(){
int s=0,w=1;
char ch=getchar();
while(ch<='0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
return s*w;
}
void hash(int x)
{
long long w=abs(x)%mo,i=0;
while (i<mo&&h[(w+i)%mo][0]!=-1&&h[(w+i)%mo][0]!=x) i++;
if (h[(w+i)%mo][0]==-1)
{
h[(w+i)%mo][0]=x;
h[(w+i)%mo][1]++;
tj++;
a[tj]=x;
} else
if (h[(w+i)%mo][0]==x) h[(w+i)%mo][1]++;
}
int main()
{
int n,c;
n=read();c=read();
memset(h,-1,sizeof(h));
for (int i=1;i<=n;i++)
{
long long w;
w=read();
hash(w);
}
sort(a+1,a+tj+1);
for (int i=1;i<=tj;i++)
{
int w=find(a[i]+c),z=find(a[i]);
if (h[w][0]==a[i]+c&&h[z][0]==a[i]) ans=(long long)ans+(long long)(h[z][1]+1)*(long long)(h[w][1]+1);
}
printf("%lld",ans);
return 0;
}