#尺取法 --由codeforces 701C They are EveryWhere为例
2016-07-27 15:17
351 查看
尺取法
首先,尺取法就是形如一把尺子的方法,去一块一块的截取你所需要的序列。
接下来将由一个经典的尺取法例子和codeforces上的一道题对尺取法进行分析。
由简单起见,从经典的例子开始分析:
1.经典的例子
给定一个长度为n的数列a1,a2……an及整数S,求不小于S的连续子序列的和的最小值。若解肯定存在。
尺取法示意图:
首先,取得满足条件的最小序列,然后依次将i向右移动,若i向左移动的过程中序列仍然满足条件,则j不移动,否则将j也向右移动。在移动的过程中记录j-i的最小值。
2.codeforces /701C
C. They Are Everywhere
time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard 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.
Input
The 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.
Output
Print 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
题意大致:输入n长度的字母序列,求出包含所有种类字母的最小序列。和上一题截图思路一致。
思路: 1.首先记录字母序列的包含所有种类个数
2.用尺取法从左开始取得包含满足所有种类字母的序列,记录序列长度
3.一次将i向右移动(下列的代码中的i用end代替)若i移动的过程中序列仍然满足包含所有种类的长度,则记录序列长度;否则将j向右移动直到序列满足包含所有种类(下列的代码中j用first代替)。
代码如下:
首先,尺取法就是形如一把尺子的方法,去一块一块的截取你所需要的序列。
接下来将由一个经典的尺取法例子和codeforces上的一道题对尺取法进行分析。
由简单起见,从经典的例子开始分析:
1.经典的例子
给定一个长度为n的数列a1,a2……an及整数S,求不小于S的连续子序列的和的最小值。若解肯定存在。
input n=10,S=15 a={5,1,3,5,10,7,4,9,2,8}
尺取法示意图:
首先,取得满足条件的最小序列,然后依次将i向右移动,若i向左移动的过程中序列仍然满足条件,则j不移动,否则将j也向右移动。在移动的过程中记录j-i的最小值。
<span style="font-size:18px;">#include<cstdio> #include <cstring> #include<cmath> #include<iostream> #include<algorithm> using namespace std; int n; int a[200000]; int main() { int n,max,sum; cin>>n>>max; for(int k = 0 ; k < n ; k++) cin>>a[k]; int i = 0,j = 0,sum = 0,ans = n+1; while(1) { while(j < n && sum < max)//sum<max时不断循环,使得取得满足条件的序列 sum += a[j++]; if(sum < max) break; //若j>=n且sum小于max则输出 ans = min(j-i,ans); //记录最小的尺度 sum -= a[i++]; //i向右移动 } cout << ans << endl; return 0; }</span>
2.codeforces /701C
C. They Are Everywhere
time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard 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.
Input
The 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.
Output
Print 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
题意大致:输入n长度的字母序列,求出包含所有种类字母的最小序列。和上一题截图思路一致。
思路: 1.首先记录字母序列的包含所有种类个数
2.用尺取法从左开始取得包含满足所有种类字母的序列,记录序列长度
3.一次将i向右移动(下列的代码中的i用end代替)若i移动的过程中序列仍然满足包含所有种类的长度,则记录序列长度;否则将j向右移动直到序列满足包含所有种类(下列的代码中j用first代替)。
代码如下:
#include<cstdio> #include <cstring> #include<cmath> #include<iostream> #include<algorithm> #include<vector> #include <map> #include <queue> using namespace std; const int N = 100001; # define PI 3.141592657 const int M=2e5+7; const int inf=1e9; int main() { int n; while (cin >> n) { char a ; int letter[52]; int type = 0; cin >> a; memset(letter, 0, sizeof(letter)); for (int i = 0; i < n; i++) { if(letter[a[i]-'A']==0&&a[i]<'a') { letter[a[i]-'A'] = 1; type++; }else if(letter[a[i]-'G']==0&& a[i]>='a'){ letter[a[i]-'G'] = 1; type++; } } int first = 0,end = 0, species = 0; int letterflag[52]; int ans = n+1; memset(letterflag,0,sizeof(letterflag)); while (1) { while (first < n && species < type) { if( a[first]<'a'){ if(letterflag[a[first]-'A']==0 ){ species++; } letterflag[a[first]-'A' ]++; first ++; }else{ if(letterflag[a[first]-'G']==0 ){ species++; } letterflag[a[first]-'G' ]++; first ++; } } if(species<type)break; ans = min(ans, first - end); if (a[end]<'a') { if (--letterflag[a[end]-'A'] ==0) { species --; } }else{ if (--letterflag[a[end]-'G'] ==0) { species --; } } end++; } cout << ans ; } return 0; }
相关文章推荐
- 书评:《算法之美( Algorithms to Live By )》
- 动易2006序列号破解算法公布
- C#递归算法之分而治之策略
- Ruby实现的矩阵连乘算法
- C#插入法排序算法实例分析
- C#算法之大牛生小牛的问题高效解决方法
- C#算法函数:获取一个字符串中的最大长度的数字
- 超大数据量存储常用数据库分表分库算法总结
- C#数据结构与算法揭秘二
- C#冒泡法排序算法实例分析
- 算法练习之从String.indexOf的模拟实现开始
- C#算法之关于大牛生小牛的问题
- C#实现的算24点游戏算法实例分析
- 经典排序算法之冒泡排序(Bubble sort)代码
- c语言实现的带通配符匹配算法
- 浅析STL中的常用算法
- 算法之排列算法与组合算法详解
- C++实现一维向量旋转算法
- Ruby实现的合并排序算法
- C#折半插入排序算法实现方法