#关于双指针的一些总结

烤火取暖问题:https://www.cnblogs.com/ymzjj/p/9782296.html
这里就是尺取法的一个典型的利用,因为给了框定的半径r,再依次在此基础上寻找合理的,继续向下,直至跳出循环。

#include<bits/stdc++.h>
using namespace std;
int a[1005];
int main()
{
	int n,r;
	cin>>n>>r;
	for(int i=0;i<n;i++) cin>>a[i];
	int cur=0;
	int cnt=0;
	while(cur<n)
	{
		int flag=-1;
		for(int i=0;i<n;i++)
		{
			if(a[i]){
				if(i-r+1<=cur&&i+r-1>=cur){
					flag=i;
				}
			}
		}
		if(flag==-1){
			cout<<"-1"<<endl;
			return 0;
		}
		cnt++;
		cur=flag+r;
	}
	cout<<cnt<<endl;
	return 0;
}

经典双指针1:https://www.it610.com/article/5574531.htm

#include <bits/stdc++.h>
using namespace std;
#define maxn 311111
long long a[maxn];
long long sum[maxn];
int n,k;
int main () {
    cin>>n>>k;
    sum[0]=0;
    for (int i = 1; i <= n; i++) {
        cin>>a[i];
        sum[i]= sum[i-1]+(a[i]==0);
    }
	if(!k){
		int ans=0;
		int now=0;
		for(int i=1;i<=n;i++)
		{
			if(a[i]==1){
				now++;
			}else{
				ans=max(ans,now);
				now=0;
			}
		}
		ans=max(ans,now);
		cout<<ans<<endl;
		for(int i=1;i<=n-1;i++) cout<<a[i]<<" ";
		cout<<a[n]<<endl;
		return 0;
	}else{
		int l=1,r=1,ans=0,x,y;
		for(r=1;r<n&&sum[r+1]<=k;r++){
		}
		ans=r-l+1;
		x=l;
		y=r;
		for(l=2;l<=n;l++){
			while(sum[r+1]-sum[l-1]<=k&&r+1<=n){
				r++;
			}
			if(ans<r-l+1){
				ans=r-l+1;
				x=l;
				y=r;
			}
		}
		cout<<ans<<endl;
		for(int i=x;i<=y;i++) a[i]=1;
		for(int i=1;i<=n-1;i++) cout<<a[i]<<" ";
		cout<<a[n]<<endl;
		return 0;
	}
}

经典双指针问题2(可参考1的代码,但是会TLE):https://blog.csdn.net/swust_zeng_zhuo_k/article/details/76449513

#include<bits/stdc++.h>
using namespace std;
int main()
{
	int n;cin>>n;
	char a[n+5];
	for(int i=0;i<n;i++) cin>>a[i];
	int q;cin>>q;
	while(q--){
		int k;cin>>k;
		char m;cin>>m;
		int cnt=0;
		int ans=0;
		int num=0;
		for(int i=0;i<n;i++){
			if(a[i]!=m) cnt++;
			while(cnt>k){
				if(a[num]!=m){
					cnt--;
				}
				num++;
			}
			ans=max(ans,i-num+1);
		}
		cout<<ans<<endl;		
	}
}

Problem D:
题目大意是:输入n,再输入n个数,求这些数的差在5以内最多能涵盖几个?

#include<bits/stdc++.h>
using namespace std;
int cmp(int a,int b){
	return a<b;
}
int main()
{
	int n;
	while(cin>>n){
		int cnt=0;
		int a[n+5];
		for(int i=0;i<n;i++){
			cin>>a[i];
		}
		sort(a,a+n,cmp);
		int l=0,r=1;
		while(l<n-1&&r<n){
			if(a[r]-a[r-1]>5){
				cnt=max(cnt,r-l-1);
				l=r;
				r++;
			}
			else if(a[r]-a[l]>5){
				cnt=max(cnt,r-l-1);
				l++;
				if(l==r) r++;				
			}
			else{
				r++;
			}
		}
		cnt=1+max(cnt,r-l-1);
		cout<<cnt<<endl;
	}
	return 0;
}

Problem E
白浅吃糖果(hard version)
描述
白浅喜欢吃糖,有一天她到了一个可以免费吃糖果的游乐园。游乐园摆放着一排共n个糖果,对于任意的i(1<=i<n-1),第i个糖果与第i+1个糖果相邻

第i个糖果具有一个甜度值ai。因为吃甜食太多了会得蛀牙,所以白浅吃的糖果的甜度值总和不能超过k。她可以选择一个区间然后吃掉区间内所有糖果,请问她最多能吃多少个糖果?
输入
第一行给出两个正整数n,k (1<=n<=2e5,1<=k<=1e9),意义如题面所示第二行有n个整数,分别代表每一个糖果的甜度a(1<=a<=1e9)
输出
输出一行一个整数代表白浅最多可以吃掉的糖果数。

#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
ll a[200005];
int main()
{
	ll n,t;
	while(cin>>n>>t){
		for(ll i=1;i<=n;i++){
			cin>>a[i];
		}
		ll ans=0,l=1,cnt=0;
		for(int i=1;i<=n;i++){
			ans+=a[i];
			while(ans>t){
				ans-=a[l];
				l++;
			}
			cnt=max(cnt,i-l+1);				
		}
		cout<<cnt<<endl;
	}
}
发布了71 篇原创文章 · 获赞 5 · 访问量 3425

猜你喜欢

转载自blog.csdn.net/Rainfoo/article/details/100635621
今日推荐