顾名思义,像尺子一样取一段,尺取法通常是对数组保存一对下标,即所选取的区间的左右端点,然后根据实际情况不断地推进区间左右端点以得出答案。尺取法比直接暴力枚举区间效率高很多,尤其是数据量大的时候,所以说尺取法是一种高效的枚举区间的方法,是一种技巧,一般用于求取有一定限制的区间个数或最短的区间等等。当然任何技巧都存在其不足的地方,有些情况下尺取法不可行,无法得出正确答案,所以要先判断是否可以使用尺取法再进行计算。
//题1(反向扫描):
//输入n(n<10000)个整数,放在数组a[]中,找出其中的两个数,它们
//之和等于整数m(假定肯定有解),且所有整数都是int型。
//输入第一行是a[]里的内容,第二行是m的值
//输出相加等于m的数
#include <iostream>
#include <algorithm>
using namespace std;
void find_sum(int a[],int n,int m)
{
sort(a,a+n);
int i = 0,j = n-1;
while(i<j)
{
int sum = a[i] + a[j];
if(sum>m)j--;
if(sum<m)i++;
if(sum==m)
{
cout<<a[i]<<" "<<a[j]<<endl;
i++;
}
}
}
int main()
{
int a[10000],m,i=0;
while(a[i]!=0)
{
cin>>a[i];
i++;
}
cin>>m;
find_sum(a,i,m);
return 0;
}
//尺取法
//题2(反向扫描):
//输入一个正整数n,表示测试实例的个数,后面输入n个字符串
//输出如果是回文串,输出yes,否则输出no
#include<iostream>
using namespace std;
int main()
{
int n;
cin>>n;
while(n--)
{
string s;
cin>>n;
bool ans = true;
int i = 0,j = s.size() - 1;
while(i<j)
{
if(s[i]!=s[j])
{
ans = false;
break;
}
i++;
j--;
}
if(ans)
cout<<"yes"<<endl;
else
cout<<"no"<<endl;
}
return 0;
}
//尺取法
//题3(同向扫描):
//给定一个长度为n的数组a[]和一个数,在这个数组中找一个区间,使这个区间的数组元素之和等于s。
//输出区间的起点和终点位置。
//输入样例是第一行是数组 有多少个数
//第二行是数组里的数
//第三行是区间要求的和
void findsum(int *a,int n,int s)
{
int i=0,j=0;
int sum = a[0];
while(j<n)
{
if(sum>=s)
{
if(sum==s)
{
cout<<i<<" "<<j<<endl;
}
sum-=a[i];
i++;
if(i>j)
{
sum=a[i];
j++;
}
}
if(sum<s)
{
j++;
sum+=a[j];
}
}
}
输入: s = 7, nums = [2,3,1,2,4,3] 输出: 2 解释: 子数组 [4,3] 是该条件下的长度最小的子数组。
代码如下:
#include<iostream>
#include<vector>
using namespace std;
int minSubArrayLen(int s, vector<int>& nums)
{
int len = nums.size();
int min_len = len + 1; // 初始化最小长度
int l = 0, r = -1; // 定义左右指针
int sum = 0; // 定义累加和
while(l < len){ // 左指针移动
if(sum < s && r + 1 < len)
{ // 如果累加和小于s且右指针未越界
r++;
sum += nums[r];
}
else
{ // 否则左指针向右移动
sum -= nums[l];
l++;
}
if(sum >= s)
{ // 如果累加和大于等于s,更新最小长度
min_len = min(min_len, r - l + 1);
}
}
if(min_len == len + 1)
{ // 如果最小长度未被更新,说明没有符合条件的子数组
return 0;
}
else
{
return min_len;
}
}
int main()
{
int s = 7;
vector<int> nums = {2,3,1,2,4,3};
cout<<minSubArrayLen(s, nums)<<endl; // 输出2
return 0;
}