2025.2.7

双指针

双指针实践上算是一种思想技巧,很灵活。说是双指针,但是我们在实际上使用的时候直接模拟进行就行,不过我们单独使用双指针的时候通常都是需要单调性,不然就是在其他的数据结构上进行。

比如我们需要找出一个数组中,一段1的连续最长长度或者 乘积/和 小于一定值的一定长度是多少。这个样子就是很典型的双指针。然后我们在使用只针对时候主要有快慢左右和对撞这种用法。

然后下面是部分的例子。我个人不喜欢直接用指针的 :(

P1147 连续自然数和

首项加末项乘以项数除以二。发现对于一个起点,往后最接近的终点长度是一定的。我们就可以从前往后枚举区间,暴力显然超时所以双指针很自然的出来了,不过还可以用数学方法优化。

	while(l<=r&&r<n)
	{
		int x=calc(l,r);
		if(x==n)
		{
			cout<<l<<' '<<r<<endl;
			r++;
		}
		else if(x<n)
			r++;//小了就得吧区间和扩大,所以右端点往右
		else
			l++;
	}

P1102 A-B 数对

讲实话,这个就是打个闪。我想法优先是映射和二分,然后试了试map就过了 ^^

双指针的做法应该是记录出现册数然后实际去根据C+B=A去枚举计算,然后映射和二分就暴力的很了

	for(int i=1;i<=n;i++)
	{
		cin>>num[i];
		maps[num[i]]++;
		num[i]-=m;
	}
	for(int i=1;i<=n;i++)
		ans+=maps[num[i]];
	cout<<ans<<endl;

P3143 [USACO16OPEN] Diamond Collector S

双指针从左和右边去记录两端的最大值,然后分别记录左端右端最大的差小于等于k的学列,然后最后枚举所有的电

	for(int i=2;i<=n;i++)
	{
		while(a[i]-a[now]>k)
		now++;
		l[i]=max(l[i-1],i-now+1);
	}
	now=n;
	for(int i=n-1;i>=1;i--)
	{
		while(a[now]-a[i]>k)
		now--;
		r[i]=max(r[i+1],now-i+1);
	}
	for(int i=1;i<n;i++)
	{
		ans=max(ans,l[i]+r[i+1]);
	}
	

P3029 [USACO11NOV] Cow Lineup S

有没有觉得似曾相识;双指针做法我们肯定是要坐标先排序(确定单调性才能有判断性的去移动指针)

范围从小到大,r在最左端向右一定,然后一直到各个种类都出现了,然后可以记录,然后移动l然后再去重复上述操作,注意我们维护出现次数的时候的加加减减别漏了(

和‘生日礼物’和‘逛画展’都有点像,此外暴力map存种类去写然后也行

P6465 [传智杯 #2 决赛] 课程安排

注意读题去思考里面的限制

   		while(l<=n&&l<=r)
   		{
	        while(a[r]!=a[r+1]&&r<n)
				r++;//去找最大的合法右端点
	        for(int i=l;i<=r;i++)
	        {
	        	if(i-l+1>=m)
	        	{//长度符合要求
	        		cnt[a[i-m+1]]++; //把头的数字出现次数++
					ans+=i-l+1-m+1-cnt[a[i]];	//当前长度减去必需长度剩下的都是能够选的,但是要减去i出现次数,因为首位不能一样
				}
			}    
			for(int i=l;i<=r;i++)
	            cnt[a[i]]=0;//以这个r为终点进行枚举结束所以清零
			r++;//然后以r+1为新的起点去寻找	
			l=r;
   		}

P1381 单词背诵

是不是和上面的那个拍照也是有点像

	while(1)
	{
		if(!cnt)
		{
			while(!vis[b[r]])		
				r--;
			ans=min(ans,r-l);
			
			if(flag[b[r]]>=1)
			{
				if(flag[b[r]]==1)
				{
					cnt++;
				}
				flag[b[r]]--;
				r--;
			}
				
		}
		else
		{
			if(!l)
			break;
			if(vis[b[l]])
			{
				if(!flag[b[l]])
				{
					cnt--;
				}
				flag[b[l]]++;
			}
			
			l--;
		}
	}
posted @ 2025-02-07 15:09  Hehe_o  阅读(27)  评论(0)    收藏  举报