题意:给你n个饼干,包含k种饼干,让你选连续的饼干,满足每种饼干的最小需求,且不大于最大限制。
也是昨天比赛的题目,当时只想到这题可以用线段树做,结果搜题解说这是一题水题,主要是贪心思想,枚举当前串的尾巴,串头用贪心处理,只要大于最小的需求,则头指针都可以后移,当然要统计串里面的每种饼干数量,和满足条件的饼干种数。然后注意一下,每种饼干最小需求可能为负数。很神奇的是别人的在输入的时候就continue都能过,我感到异常的神奇,所以以为那应该没有负数,结果wa了几次,后面加了几过了,很神奇啊,后面证明没有负数,但是存在0,所以他们这样做能过,如果有负数他们一定会wa。要谨记同类错误。
Run ID | Submit Time | Judge Status | Problem ID | Language | Run Time(ms) | Run Memory(KB) | User Name |
2629127 | 2011-08-16 00:09:41 | Accepted | 3297 | C++ | 830 | 1776 | xym |
#include<cstdio>
#include<cstring>
#include<cmath>
#include<string>
#include<iostream>
#include<algorithm>
using namespace std;
int q[2050],a[400005],x[2050],y[2050];
bool vs[2050],vd[2050];
int main()
{
int n,m,len,ans;
while(scanf("%d%d",&n,&m)!=EOF){
memset(vs,0,sizeof(vs));
for(int i=0;i<n;i++)
scanf("%d",a+i);
len=0;
for(int i=1;i<=m;i++){
scanf("%d%d",x+i,y+i);
if(x[i]==0&&y[i]>=0)
len++,vs[i]=true;
else
vs[i]=true;
}
if(len==m){
printf("0\n");
continue;
}
int j=0;ans=1<<20;len=0;
memset(q,0,sizeof(q));
memset(vd,0,sizeof(vd));
for(int i=0;i<n;i++)
{
q[a[i]]++;
if(vd[a[i]]==false&&q[a[i]]<=y[a[i]]&&q[a[i]]>=x[a[i]]&&vs[a[i]]==1)
len++,vd[a[i]]=true;
else if(vd[a[i]]==true&&(q[a[i]]>y[a[i]]||q[a[i]]<x[a[i]])&&vs[a[i]]==1)
len--,vd[a[i]]=false;
while(j<i&&q[a[j]]>x[a[j]])
{
q[a[j]]--;
if(vd[a[j]]==false&&q[a[j]]<=y[a[j]]&&q[a[j]]>=x[a[j]]&&vs[a[j]]==1)
len++,vd[a[j]]=true;
j++;
}
if(len==m)
ans=min(ans,i-j+1);
}
if(ans!=1<<20)
printf("%d\n",ans);
else
printf("-1\n");
}
return 0;
}