zoj 3297

题意:给你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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值