当前位置: 首页 > news >正文

P1102 A-B 数对

题目背景

出题是一件痛苦的事情!

相同的题目看多了也会有审美疲劳,于是我舍弃了大家所熟悉的 A+B Problem,改用 A-B 了哈哈!

## 题目描述

给出一串正整数数列以及一个正整数 $C$,要求计算出所有满足 $A - B = C$ 的数对的个数(不同位置的数字一样的数对算不同的数对)。

## 输入格式

输入共两行。

第一行,两个正整数 $N,C$。

第二行,$N$ 个正整数,作为要求处理的那串数。

## 输出格式

一行,表示该串正整数中包含的满足 $A - B = C$ 的数对的个数。

## 输入输出样例 #1

### 输入 #1

```
4 1
1 1 2 3
```

### 输出 #1

```
3
```

## 说明/提示

对于 $75\%$ 的数据,$1 \leq N \leq 2000$。

对于 $100\%$ 的数据,$1 \leq N \leq 2 \times 10^5$,$0 \leq a_i <2^{30}$,$1 \leq C < 2^{30}$。

2017/4/29 新添数据两组


先想暴力搜索

import java.util.Scanner;
import java.util.Arrays;

public class Main {
    private static int[] nums;
    private static int sum;
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        int N = scan.nextInt();
        int C = scan.nextInt();
        nums = new int[N];
        for (int i = 0; i < N; i++) {
            nums[i] = scan.nextInt();
        }
        Arrays.sort(nums);
        for (int i = nums.length - 1; i >= 0; i--) {
            for (int j = i - 1; j >= 0; j--) {
                if(nums[i] - nums[j] == C)
                    sum ++;
            }
        }
        System.out.println(sum);
    }
}

一边使用二分

import java.util.Scanner;
import java.util.Arrays;

public class Main {
    private static int[] nums;
    private static int C;
    private static int sum;

    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        int N = scan.nextInt();
        int C = scan.nextInt();
        nums = new int[N + 1];
        for (int i = 1; i <= N; i++) {
            nums[i] = scan.nextInt();
        }
        Arrays.sort(nums);
        for (int i = nums.length - 1; i >= 0; i--) {
            binarySearch(0,i + 1,nums[i] - C);
        }
        System.out.println(sum);
    }

    private static void binarySearch(int left,int right,int tar) {
        if(tar < nums[1] || tar > nums[nums.length - 1])
            return;
        int rigB = right;
        int mid = 0;
        while(left + 1 < right) {
            mid = (left + right) / 2;
            if(isBlue(mid,tar))
                left = mid;
            else
                right = mid;
        }
        if(nums[right] != tar)
            return;
        for (int i = right; i < rigB; i++) {
            if(nums[i] == tar)
                sum ++;
        }
    }

    private static boolean isBlue(int x,int tar) {
        return nums[x] < tar;
    }

}

两边使用二分但是没有开long

import java.util.Scanner;
import java.util.Arrays;

public class Main {
    private static int[] nums;
    private static int C;
    private static int sum;

    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        int N = scan.nextInt();
        int C = scan.nextInt();
        nums = new int[N + 1];
        for (int i = 1; i <= N; i++) {
            nums[i] = scan.nextInt();
        }
        Arrays.sort(nums);
        for (int i = nums.length - 1; i >= 0; i--) {
            int leftB = binarySearch(0, i + 1, nums[i] - C);
            if (leftB == -1)
                continue;
            int rigB = binarySearch02(0,i + 1,nums[i] - C);
            sum += rigB - leftB + 1;
        }
        System.out.println(sum);
    }

    private static int binarySearch(int left, int right, int tar) {
        if (tar < nums[1] || tar > nums[nums.length - 1])
            return -1;
        int rigB = right;
        int mid = 0;
        while (left + 1 < right) {
            mid = (left + right) / 2;
            if (isBlue(mid, tar))
                left = mid;
            else
                right = mid;
        }
        if (nums[right] == tar)
            return right;
        return -1;
    }

    private static int binarySearch02(int left, int right, int tar) {
        int mid = 0;
        while (left + 1 < right) {
            mid = (left + right) / 2;
            if (isRed(mid, tar))
                right = mid;
            else
                left = mid;
        }
        if(nums[left] == tar)
            return left;
        return -1;
    }

    private static boolean isBlue(int x, int tar) {
        return nums[x] < tar;
    }

    private static boolean isRed(int x, int tar) {
        return nums[x] > tar;
    }

}

开了long之后过了

import java.util.Scanner;
import java.util.Arrays;

public class Main {
    private static int[] nums;
    private static int C;
    private static long sum;

    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        int N = scan.nextInt();
        int C = scan.nextInt();
        nums = new int[N + 1];
        for (int i = 1; i <= N; i++) {
            nums[i] = scan.nextInt();
        }
        Arrays.sort(nums);
        for (int i = nums.length - 1; i >= 0; i--) {
            int leftB = binarySearch(0, i + 1, nums[i] - C);
            if (leftB == -1)
                continue;
            int rigB = binarySearch02(0,i + 1,nums[i] - C);
            sum += rigB - leftB + 1;
        }
        System.out.println(sum);
    }

    private static int binarySearch(int left, int right, int tar) {
        if (tar < nums[1] || tar > nums[nums.length - 1])
            return -1;
        int rigB = right;
        int mid = 0;
        while (left + 1 < right) {
            mid = (left + right) / 2;
            if (isBlue(mid, tar))
                left = mid;
            else
                right = mid;
        }
        if (nums[right] == tar)
            return right;
        return -1;
    }

    private static int binarySearch02(int left, int right, int tar) {
        int mid = 0;
        while (left + 1 < right) {
            mid = (left + right) / 2;
            if (isRed(mid, tar))
                right = mid;
            else
                left = mid;
        }
        if(nums[left] == tar)
            return left;
        return -1;
    }

    private static boolean isBlue(int x, int tar) {
        return nums[x] < tar;
    }

    private static boolean isRed(int x, int tar) {
        return nums[x] > tar;
    }

}

二分用不用还是依据时间复杂度来看的!

会二分发现那里不够用,可以用二分。把那个问题转化为二分问题

甚至可以进一步分析


找好的老师,这次找了——会code的小金鱼——几乎是马上就学会了二分!!!!!!!!!!

二分查找 | 妈妈再也不怕我写错二分啦 | 五点七边二分视频补充_哔哩哔哩_bilibili

二分查找为什么总是写错?_哔哩哔哩_bilibili

二分习题课 | 手把手教你二分答案! | 超级细不听血亏_哔哩哔哩_bilibili

相关文章:

  • github_本地项目上传到远程
  • python 模拟登录
  • 阶跃星辰 Step-Video-TI2V 图生视频模型深度解析
  • 自由学习记录(47)
  • 10分钟读完《有限与无限的游戏》
  • 两个手机都用流量,IP地址会一样吗?深入解析
  • 【计算机网络】TCP协议技术细节全解析:与UDP的核心差异深度对比
  • 餐饮管理系统的设计与实现(代码+数据库+LW)
  • 新书速览|云原生Kubernetes自动化运维实践
  • 2024年数维杯数学建模B题生物质和煤共热解问题的研究解题全过程论文及程序
  • Linux运维篇-系统io调优
  • 《基于Python的财务数据可视化与决策支持系统开发》开题报告
  • 如何用大模型评估大模型——PAI-Judge裁判员大语言模型的实现简介
  • 2. 初识go-zero
  • Linux系统还可以在做一层虚拟化安装虚拟机吗
  • 基于Python的超导体金属研制探索与展望
  • 嵌入式c学习八
  • ASP.NET Core部署Docker教程
  • CentOS 7上配置虚拟用户的FTP服务
  • 【论文阅读】大型语言模型能否实现软件漏洞的检测与修复?
  • 河南发布高温橙警:郑州、洛阳等地最高气温将达40℃以上
  • 去年上海全市博物馆接待观众约4087万人次,同比增31.9%
  • 外交部驻港公署正告美政客:威胁恫吓撼动不了中方维护国家安全的决心
  • 夜读丨什么样的前程值得把春天错过
  • “85后”贵阳市政府驻重庆办事处主任吴育材拟任新职
  • 联合国第二届运动会闭幕,刘国梁受邀成为“联合国运动会大使”