就是两个指针表示区间[l,r]的开始与结束然后根据题目来将端点移动,是一种十分有效的做法。适合连续区间的问题
具体做法是:
1.初始化左右端点
2.不断扩大右端点,直到满足条件
3.如果第二步中无法满足条件,则终止,否则更新结果
4.将左端点扩大1,然后回到第二步
几个例子:
1、Codeforces Round #364 (Div. 2) 点击打开链接
C. They Are Everywhere time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output
Sergei B., the young coach of Pokemons, has found the big house which consists of n flats ordered in a row from left to right. It is possible to enter each flat from the street. It is possible to go out from each flat. Also, each flat is connected with the flat to the left and the flat to the right. Flat number 1 is only connected with the flat number 2 and the flat number n is only connected with the flat number n - 1.
There is exactly one Pokemon of some type in each of these flats. Sergei B. asked residents of the house to let him enter their flats in order to catch Pokemons. After consulting the residents of the house decided to let Sergei B. enter one flat from the street, visit several flats and then go out from some flat. But they won't let him visit the same flat more than once.
Sergei B. was very pleased, and now he wants to visit as few flats as possible in order to collect Pokemons of all types that appear in this house. Your task is to help him and determine this minimum number of flats he has to visit.
InputThe first line contains the integer n (1 ≤ n ≤ 100 000) — the number of flats in the house.
The second line contains the row s with the length n, it consists of uppercase and lowercase letters of English alphabet, the i-th letter equals the type of Pokemon, which is in the flat number i.
OutputPrint the minimum number of flats which Sergei B. should visit in order to catch Pokemons of all types which there are in the house.
Examples input 3 AaA output 2 input 7 bcAAcbc output 3 input 6 aaBCCe output 5 NoteIn the first test Sergei B. can begin, for example, from the flat number 1 and end in the flat number 2.
In the second test Sergei B. can begin, for example, from the flat number 4 and end in the flat number 6.
In the third test Sergei B. must begin from the flat number 2 and end in the flat number 6.
题意:长度为n的字符串,包含大小写字母,求最短的连续子串的长度, 使得子串中包含所有在原字符串中出现过的字母。 思路:这里用到尺取法。AC代码:
<span style="font-size:14px;">#include<stdio.h> #include<string.h> int main() { int n,temp=0,i,ans;char s[100010];int a[200]; memset(a,0,sizeof(a)); scanf("%d",&n); scanf("%s",s); for(i=0;i<n;i++) { a[s[i]]=1; } for(i=65;i<=122;i++) if(a[i]) temp++; memset(a,0,sizeof(a)); int l=0,r=0,now=1;ans=n+1; a[s[l]]=1; while(1) { while(r<n-1) { if(now==temp) break; r++; if(!a[s[r]]) {now++;} a[s[r]]++; } if(now<temp) break; if(r-l+1<ans) ans=r-l+1; if((--a[s[l]])==0) now--; l++; } printf("%d\n",ans); }</span>
2、POJ 2566 点击打开链接
Bound Found Time Limit: 5000MS Memory Limit: 65536KTotal Submissions: 2906 Accepted: 892 Special JudgeDescription
Signals of most probably extra-terrestrial origin have been received and digitalized by The Aeronautic and Space Administration (that must be going through a defiant phase: "But I want to use feet, not meters!"). Each signal seems to come in two parts: a sequence of n integer values and a non-negative integer t. We'll not go into details, but researchers found out that a signal encodes two integer values. These can be found as the lower and upper bound of a subrange of the sequence whose absolute value of its sum is closest to t. You are given the sequence of n integers and the non-negative target t. You are to find a non-empty range of the sequence (i.e. a continuous subsequence) and output its lower index l and its upper index u. The absolute value of the sum of the values of the sequence from the l-th to the u-th element (inclusive) must be at least as close to t as the absolute value of the sum of any other non-empty range.Input
The input file contains several test cases. Each test case starts with two numbers n and k. Input is terminated by n=k=0. Otherwise, 1<=n<=100000 and there follow n integers with absolute values <=10000 which constitute the sequence. Then follow k queries for this sequence. Each query is a target t with 0<=t<=1000000000.Output
For each query output 3 numbers on a line: some closest absolute sum and the lower and upper indices of some range where this absolute sum is achieved. Possible indices start with 1 and go up to n.Sample Input
5 1 -10 -5 0 5 10 3 10 2 -9 8 -7 6 -5 4 -3 2 -1 0 5 11 15 2 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 15 100 0 0Sample Output
5 4 4 5 2 8 9 1 1 15 1 15 15 1 15 题意:有n个数,m次访问,每次访问找出一个连续的子序列使得他们的和最接近t。输出这个和,和序列的左右端点。思路:这里用前缀和先预处理一下,并排序,然后再用尺取法
AC代码:
#include<stdio.h> #include<string.h> #include<math.h> #include<algorithm> using namespace std; struct node { long long x,y; }b[100010]; int cmp(node a,node b) { return a.x<b.x; } int main() { long long n,k,t,a[100010],temp,ans,l,r,i,judge,ansl,ansr; while(scanf("%lld%lld",&n,&k)!=EOF&&(n!=0||k!=0)) { a[0]=0;b[0].x=0,b[0].y=0,temp=0; for(i=1;i<=n;i++) { scanf("%lld",&a[i]); temp+=a[i]; b[i].x=temp; b[i].y=i; } sort(b,b+n+1,cmp); while(k--) { l=0;r=1;judge=1<<30;long long now;ans=b[1].x;ansl=1,ansr=1; scanf("%lld",&t); while(r<=n&&judge) { now=b[r].x-b[l].x; if(abs((int)(now-t))<judge) { judge=abs((int)(now-t)); ans=now; ansl=b[l].y; ansr=b[r].y; } if(now<t) r++; if(now>t) l++; if(r==l) r++; } if(ansl>ansr) swap(ansl,ansr); printf("%lld %lld %lld\n",ans,ansl+1,ansr); } } }