您的位置:首页 > 其它

HRBUST 1293 map||二分

2013-10-07 22:56 344 查看
有n个整数,给定一个数x,从n个数中取两个数,使得和刚好为x,问有多少种取法。0 < n <= 100000

2层枚举必然超时..

map

用map的话,一层枚举,枚举到每个数str[i]即可知道x-str[i]出现与否以及出现次数,统计即可

如果str[i]*2==x的话需要特殊处理下。

二分方法

首先把数据升序排列,然后枚举.

对于每一个str[i],key=x-str[i],只需要在i之后,n-1之前找到2个下标st和ed

st是第一个str[y]>=key的y,ed是第一个str[y]>key的y,

最后判断一下 str[st]==key&&str[ed-1]==key,如果是,tot则需要加上ed-st

统计的时候需要用long long ,因为50000*50000就超int了

#include<stdio.h>
#include<algorithm>
using namespace std;
int main(){
long long str[100005],tp;
int mid;
int n,m,left,right,st,ed;
while(scanf("%d %d",&n,&m)!=EOF){
for(int i=0;i<n;i++)scanf("%lld",&str[i]);
long long tot=0;
sort(str,str+n);
for(int i=0;i<n;i++){
tp=m-str[i];
left=i+1,right=n-1;
while(right>=left){
mid=(left+right)/2;
if(str[mid]<tp)left=mid+1;
else right=mid-1;
}st=left;
left=i+1,right=n-1;
while(right>=left){
mid=(left+right)/2;
if(str[mid]<=tp)left=mid+1;
else right=mid-1;
}ed=left;
if(str[st]==tp&&str[ed-1]==tp){
tot+=ed-st;
}
}
printf("%lld\n",tot);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: