差 解题报告

这篇解题报告详细介绍了如何解决‘A-B Problem’,即在已排序的整数序列中寻找满足A-B=C的数对方案数。讨论了三种思路,包括暴力枚举、原思路优化及二分查找方法,探讨了它们的时间复杂度,并提供了输入输出样例及数据范围。

差 解题报告

D e s c r i p t i o n \rm Description Description

描述

楠楠在网上刷题,感觉第一题:求两数的和 ( ( ( A + B A+B A+B P r o b l e m Problem Problem ) ) ) 太无聊了,于是增加了一题: ( ( ( A − B A-B AB P r o b l e m Problem Problem ) ) ),难倒了一群小朋友,哈哈。
题目是这样的:给出N个从小到大排好序的整数,一个差值C,要求在这N个整数中找两个数A和B,使得A-B=C,问这样的方案有多少种?
例如: N = 5 N=5 N=5 C = 2 C=2 C=2 5 5 5 个整数是: 2 2 2 2 2 2 4 4 4 8 8 8 10 10 10 。答案是 3 3 3 。具体方案:第 3 3 3 个数减第 1 1 1 个数;第 3 3 3 个数减第 2 2 2 个数;第 5 5 5 个数减第 4 4 4 个数。

输入

第一行 2 2 2 个正整数: N , C N,C N,C 。第二行 N N N 个整数:已经有序。注意:可能有相同的。

输出

一个整数,表示该串数中包含的所有满足 A − B = C A-B=C AB=C 的数对的方案数。

输入样例

4 1

1 1 2 2

输出样例

4

提示

【数据范围】:

5 5 5 个数据: N \rm N N 的范围是 [ 1 … 1 , 000 ] [1…1,000] [11,000]

5 5 5 个数据: N \rm N N 的范围是 [ 1 … 100 , 000 ] [1…100,000] [1100,000]

【所有数据】:

C的范围是 [ 1 … 1 , 000 , 000 , 000 ] [1…1,000,000,000] [11,000,000,000]

N个整数中每个数的范围是: [ 0 … 1 , 000 , 000 , 000 ] [0…1,000,000,000] [01,000,000,000]

解题部分

思路一

首先,我们找的应该是 A − B = C A-B=C AB=C ,由小学数学得我们可以知道可以找 B + C = A B+C=A B+C=A ,所以可以直接暴力枚举 B B B C C C
时间复杂度为 O ( n 2 ) O(n^2) O(n2)

思路二(原始思路)

可以直接枚举每一个点,然后再将它左边的点一个一个减,当差大于时停止,换下一个点枚举。
时间复杂度约为 O ( n 2 ) O(n^2) O(n2)

思路三(原始思路改良版)

也是枚举每一个点,例如当前的点为B,用二分答案找到等于A的最左边的坐标,再用二分答案找到小于A的点的坐标,两个相减得到一共有多少个A,然后累加起来,最后输出。
时间复杂度为约为 O ( n 2 l o g n ) O(n2logn) O(n2logn)

	for(int i=1; i<=n; i++)//枚举每个数
	{
		int l=1, r=n;
		num=a[i]+c;//B+C=A,a[i]是B
		while(l<=r)
		{
			int mid=(l+r) >> 1;
			if(a[mid]<num) l=mid+1;
			else r=mid-1;
		}
		//找到小于A的点的坐标
		ans1=l;
		l=1,r=n;//记得要初始化!
		while(l<=r)
		{
			int mid=(l+r) >> 1;
			if(a[mid]<=num) l=mid+1;
			else r=mid-1;
		}//找到等于A的点的坐标
		ans2=l;
		ans+=ans2-ans1;
	}

提交代码地址(数据加强)

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值