HRBUST 1293 map||二分

来源:互联网 发布:免费手机考勤软件 编辑:程序博客网 时间:2024/05/22 12:34

有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;}


原创粉丝点击