二分入门洛谷p1102题解

题目是这样的:给出一串数以及一个数字 CC,要求计算出所有 A - B = CA−B=C 的数对的个数(不同位置的数字一样的数对算不同的数对)。

输入格式

输入共两行。

第一行,两个整数 N, CN,C。

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

输出格式

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

输入输出样例

输入 #1复制

4 1
1 1 2 3

输出 #1复制

3

这道题属于典型的二分查找题,但是对于初学二分者(比如我)来说,还是比较棘手的。

刚开始做的时候也没有想到用二分查找,也是看了题解之后才知道可以用二分的。尽管如此,还是仔细研究了很多遍大神的题解才明白二分查找在此题中如何应用的。

首先说一下什么是二分:

在计算机科学中,折半搜索(英语:half-interval search),也称二分搜索(英语:binary search)、对数搜索(英语:logarithmic search),是一种在有序数组中查找某一特定元素的搜索算法。

搜索过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜索过程结束;如果某一特定元素大于或者小于中间元素,则在数组大于或小于中间元素的那一半中查找,而且跟开始一样从中间元素开始比较。如果在某一步骤数组为空,则代表找不到。这种搜索算法每一次比较都使搜索范围缩小一半

 下面是二分的基本模板(二分的模板其实都一样):

left = 0, right = length - 1;
while (left <= right) {
	mid = (left + right) / 2;
	if (nums[mid] == target) return mid;
	else if (nums[mid] < target) left = mid + 1;
	else right = mid - 1;
}

// 结束后:right + 1 == left
// 每次都会询问nums[mid]是否等于target,所以不需要进行额外的后处理

 其实二分查找的概念很好理解,但是其中的细节却非常多,下面引用一个大神的研究就知道二分的复杂了:

下面我用乘法原理来告诉你们二分查找有多少种写法。

区间的开闭 - [开区间还是闭区间]
左右端点 - [这个端点是和上面区间开闭联系的,具体表现为左开还是左闭,右开还是右闭]
中点是取整还是进一 - [在计算中点的时候到底是(left + right) >> 1还是(left + right + 1) >> 1]
大于还是小于 - [这个对应上下界问题]
取不取等于 - [是大于等于还是小于等于]
第一个还是最后一个 - [找第一个大于目标的位置还是找最后一个大于目标的位置]
每个选项都是两种可能,于是二分写法一共有26=6426=64种写法。也就是说,从这六个选项中的每个选项中任意挑选一个就可以组成一个二分的问题。
————————————————
版权声明:本文为CSDN博主「FlushHip」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/FlushHip/article/details/79261608

了解完什么是二分之后,再来看一下这题。可能很多刚学二分的同学和我当时一样疑惑:这个题感觉和二分没有什么关联啊。

我们发现,如果这个数组是有序的,那么对于每一个A的值,在它的后方就只有一个数值B满足A-B=C,是不是?

这时我们只需要使用两个函数求出数组中对于每个A(A=B+C)的位置,它们的差即为数组中数值为B+C的元素个数。将这个数加到sum中。

其中,C是我们输入进去的已知数,B就是有序数组的数。采用枚举for(i=;i

当然,这道题必须注意的是同时也是二分查找的注意事项:数组必须有序!

也就是说,在我们输入数组之后,必须先对数组进行排序。但是这又引出了一个问题:如果数据过大,肯定会超时(排序我采用的是冒泡排序法),所以这里就凸显出c++的好处了:一行sort函数解决问题,因为写代码的时候是c语言和c++混合的,所以为了方便,头文件直接使用万能头文件了。

下面上代码:

#include
using namespace std;
long long n,i,m,x,c;
long long sum=0,a[100000005];
int findnum1(int x) 
{
	int tou=0;
	int wei=n+1;
	while(tou+1

这里需要注意的是,数据类型用long long类型,否则测试点3无法通过,看了别的大神的题解也是这样。

虽然二分的概念很简单,但是我仍然感觉没有学透,包括mid中间值的取法,还有边界值的确定仍然困扰着我,但是这些又是二分的精华所在,因此我还要多多练习。

你可能感兴趣的:(二分查找,c语言,数据结构)