过了但是有一个和递归内存相关的问题,望解答!
  • 板块P1102 A-B 数对
  • 楼主root1729
  • 当前回复2
  • 已保存回复2
  • 发布时间2020/11/29 11:05
  • 上次更新2023/11/5 07:06:54
查看原帖
过了但是有一个和递归内存相关的问题,望解答!
309946
root1729楼主2020/11/29 11:05
#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
const int n=200000;
int a[n+1];
int N,C;
int tfr(int n,int l,int r)
{
	if(l==r)
	{
		if(a[l]==n) return l;
		else return 0;
	}
	if(r-l==1)
	{
		int answer=0;
		if(a[r]==n) answer=r;
		else
		if(a[l]==n) answer=l;
		return answer;
	}
	int mid=(l+r)/2;
	if(n>=a[mid]) tfr(n,mid,r);
	else tfr(n,l,mid-1);
}
int tfl(int n,int l,int r)
{
	if(l==r)
	{
		if(a[l]==n) return l;
		else return 0;
	}
	if(r-l==1)
	{
		int answer=0;
		if(a[l]==n) answer=l;
		else
		if(a[r]==n) answer=r;
		return answer;
	}
	int mid=(l+r)/2;
	if(n>a[mid]) tfl(n,mid+1,r);
	else tfl(n,l,mid);
}
int main()
{
	cin>>N>>C;
	long long sum=0;
	int right,left;
	for(int i=1;i<=N;i++) scanf("%d",&a[i]);
	sort(a+1,a+1+N);
	if(C>=0)
	for(int i=N;i>=1;i--)
	{
		int B=a[i]-C;
		if(B>=a[1])
		{
			right=tfr(B,1,i);
			left=tfl(B,1,i);
			if(left!=0)
			sum+=right-left+1;
		}
		else break;
	}
	else
	for(int i=1;i<=N;i++)
	{

		int B=a[i]-C;
		if(B<=a[N])
        {
			right=tfr(B,i,N);
			left=tfl(B,i,N);
			if(left!=0)
			sum+=right-left+1;
        }
		else break;
	}
	cout<<sum;
	return 0;
}
```完整源代码如上

具体思路就是两次二分查找出有序序列中某一个数所在有限数列的左端点和右端点,要讨论的问题就在其中的二分查找的代码,单独拉出来如下:
```cpp
int tfr(int n,int l,int r)
{
	if(l==r)
	{
		if(a[l]==n) return l;
		else return 0;
	}
	if(r-l==1)
	{
		int answer=0;
		if(a[r]==n) answer=r;
		else
		if(a[l]==n) answer=l;
		return answer;
	}
	int mid=(l+r)/2;
	if(n>=a[mid]) tfr(n,mid,r);
	else tfr(n,l,mid-1);
}

ps:为了简洁,只拉出来了取左端点的函数,不影响我的讨论;

函数中刚开始是判断边界的,然后是定义中值变量,然后就是二分了;

问题就在定义中值变量这,我如果把它放在判断边界的前面,也就是函数开头,内存就会爆掉,原本只占用1.25mb左右的内存,立马爆了,可能是因为题中内存上限就是125mb,所以显示的是125。

我怎么想也想不通怎么占用内存会多出100倍以上...换一下定义中间值变量的位置不就是在一次二分过程的边界处多定义了一次中间变量嘛,也就是待查找区间还剩下一到两个元素的时候。

还有一个问题,我偶然发现的,我在函数末尾自调用函数的时候,没加return但是也运行的好好地,没有半点问题,为啥?唯一的一次传值return的值是咋一步步传回主函数的?

2020/11/29 11:05
加载中...