知识点一 搜索:尺取法 POJ 3061+ POJ 2100

尺取法知识点

概括:尺取法是用两个指针解决问题的算法
题目特征:求满足条件的最小区间
图示
在这里插入图片描述

题意

给定数字序列,求一段连续的尽可能短的子序列,使这个子序列满足条件:和大于等于S。

思路

让两个指针(数组用下标)指向初始位置,left保留在原地,right往右走,直到满足条件。
如果走到序列的最后面都没有满足条件,说明该样例无解,跟它说再见。
如果走到某个位置,满足条件了,那么让right停下来。
这时候我们看看能不能把这个子序列压缩短一点,因为这个子序列刚刚加上了这个子序列中最右边那个数字才使条件满足,所以右边没法压缩。
我们看把left往右移动一位,看看还符不符合条件,符合的话记录,不符合的话,说明压缩之前的是暂时的解,然后继续走right,不断重复上述步骤直到right走到结尾而left无法再压缩就结束。

尺取法的题目

http://poj.org/problem?id=3061**
poj 3061
模板题,按照上面的思路即可求解。
代码

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int a[100005];
int main()
{
	int T,n,s;
	scanf("%d",&T);
	while(T--){
		memset(a,0,sizeof(a));
		scanf("%d %d",&n,&s);
		int l=0,r=0,sum=0,ans=n;
		for(int i=0;i<n;i++)
			scanf("%d",&a[i]);
		while(1)
		{	
			while(r<n&&sum<s)
				sum+=a[r++];
			if(sum<s)break;
			ans=min(ans,r-l);
			sum-=a[l++];
		}	
		if(ans==n)printf("0\n");
		else printf("%d\n",ans);
	}
	return 0;
 } 

http://poj.org/problem?id=2100**
POJ - 2100

题意

题目要我们找到所有的连续数列,使得他们的平方的和等于n

模板题,按照上面写的思路即可求解。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath> 
using namespace std;
int left[10000000],right[10000000];
int main()
{
	long long n;
	scanf("%lld",&n);
	long long l=1,r=1,ans=0,sum=0;
	while(1)
	{
		while(r<=sqrt(n)+1&&sum<n) {
			sum+=r*r;
			r++;
		}
		if(sum<n)break;
		if(sum==n)left[ans]=l,right[ans++]=r;
		sum-=l*l;
		l++;
	}
	printf("%d\n",ans);
	for(int i=0;i<ans;i++){
		printf("%d",right[i]-left[i]);
		for(int j=0;left[i]+j<right[i];j++) 
			printf(" %d",left[i]+j);
		printf("\n");
	}
	return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值