• 【洛谷】【二分查找】P1102 A−B数对


    【题目描述:】

    给出一串数以及一个数字 C ,要求计算出所有 A−B=C 的数对的个数。(不同位置的数字一样的数对算不同的数对)

    【输入格式:】

    第一行包括 2 个非负整数 N 和 C ,中间用空格隔开。

    第二行有 N 个整数,中间用空格隔开,作为要求处理的那串数。

    【输出格式:】

    输出一行,表示该串数中包含的所有满足 A−B=C 的数对的个数。


    [算法分析:]

    对于前73%的数据,可以直接(O(N^2))枚举

    对于100%的数据,可以用二分优化到(O(nlog_2n))

    对于一个集合A,a∈A,b∈A

    求 a-b=c 的数对的个数,就是满足求出a=b+c的数对个数

    先把数据从小到大排序,

    枚举集合中的每一个元素b,二分找出第一个等于b+c的元素的位置pos1和第一个大于b+c元素的位置pos2

    则[pos1, pos2-1]区间内的每一个元素都能与b构成一个数对

    对于此时的b来说,能与其构成数对的方案数为pos2-pos1。


    [Code:]

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #define re register
    using namespace std;
    typedef long long LL;
    
    const int MAXN = 200000 + 1;
    
    int n, c, a[MAXN];
    LL ans;
    
    inline int abs(int x) {
    	return x>0 ? x : -x;
    }
    
    //炒鸡快读
    inline char gc()
    {
        static char buff[1000000],*S=buff,*T=buff;
        return S==T&&(T=(S=buff)+fread(buff,1,1000000,stdin),S==T)?EOF:*S++;
    }
    
    inline int read() {
    	int x = 0; char ch = gc();
    	while(!isdigit(ch)) ch = gc();
    	while(isdigit(ch))
    		x = (x << 3) + (x << 1) + ch - 48, ch = gc();
    	return x;
    }
    
    int main() {
    	n = read(), c = read();
    	for(re int i=1; i<=n; ++i) a[i] = read();
    	sort(a + 1, a + n + 1);
    	for(re int i=1; i<=n; ++i) {
    		int pos1 = lower_bound(a+1, a+n+1, a[i]+c)-a;
    		int pos2 = upper_bound(a+1, a+n+1, a[i]+c)-a;
    		ans += pos2-pos1;
    	}
    	printf("%lld
    ", ans);
    }
    
  • 相关阅读:
    HBase 文件读写过程描述
    Kafka 部署指南-好久没有更新博客了
    《Python高性能编程》——列表、元组、集合、字典特性及创建过程
    Ansible常用功能
    vim内替换文件内容
    线程队列-queue
    Python多进程
    python多线程知识-实用实例
    夜间模式的实现
    本地通知的实现
  • 原文地址:https://www.cnblogs.com/devilk-sjj/p/9209902.html
Copyright © 2020-2023  润新知