题意:已知一行羊圈两两相连,中间由一个栅栏分开。给栅栏编号1-n,那么一共有n-1个羊圈。给定m个羊所在的位置,比如一个羊在x,那么表示他在x和x+1所围住的羊圈中。再给定一个常数c,求最大的连续区间,使得其中的羊总数不超过c。
思路:贪心即可。设两个游标i和j,扫一遍。相当于求固定起点i能够符合条件的最长的区间。
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <queue>
using namespace std;
#define INF 0x3fffffff
#define clr(s,t) memset(s,t,sizeof(s))
#define N 1005
int n,m,c;
int s[N];
int main(){
int i,j,x,res,num;
scanf("%d %d %d",&m,&n,&c);
clr(s, 0);
for(i = 0;i<m;i++){
scanf("%d",&x);
s[x]++;
}
res = num = 0;
for(i = j = 1;i<n;i++){
num -= s[i-1];
while(num <= c && j<n){
num += s[j];
j++;
}
res = max(res,j-i-1);
if(j == n){
if(num <= c)//忘了判断这个wa了一次
res = max(res,j-i);
break;
}
}
printf("%d\n",res);
return 0;
}
poj3061题意:求一个子序列的长度,这个子序列之和必须大于指定的一个值limit,且必须长度最小,求出这个序列的最小长度。
思路:同上,设置两个游标,从左到右扫一遍O(n)即可。如果预处理求出前n项和数组,在之上处理会更方便。
#include <cstdio>
#include <queue>
#include <algorithm>
#include <cstring>
using namespace std;
#define INF 0x3fffffff
#define clr(s,t) memset(s,t,sizeof(s));
#define N 100005
int s[N],n,m,T;
int main(){
scanf("%d",&T);
while(T--){
int i,j,res=INF,now = 0;
scanf("%d %d",&n,&m);
for(i = 1;i<=n;i++)
scanf("%d",&s[i]);
for(i = 1,j = 0;j<=n;){
while(now<m && j<n)
now += s[++j];
if(now<m && j>=n)
break;
res = min(res,j-i+1);
while(now >= m && i<j)
now -= s[i++];
if(now>=m && i==j){
res = 1;
break;
}
res = min(res,j-i+2);
}
if(res == INF)
printf("0\n");
else
printf("%d\n",res);
}
return 0;
}