NKOJ——P1095——气球游戏

原题

问题描述

何老板在磁器口摆摊提供打气球游戏。就是在一大块布上挂满各种颜色的小气球,游客可以花钱购买气枪子弹,然后用何老板提供的气枪在远处射击气球。
何老板提供了一种奖励,就是如果在连续T枪中打爆了所有颜色的气球,将得到一只泰迪熊作为奖励。(注意:不是所有的气球,而是所有颜色的气球,也就是每种颜色的气球至少被打爆一只)
总共有m种不同颜色的气球,编号1到m。一个游客买了n发子弹,然后连续开了n枪。何老板想知道在这n枪中,游客打爆所有颜色的气球,最少用了连续几枪?

输入格式

第一行两个空格间隔的整数数n,m。
第二行一共n个空格间隔的整数,分别表示每一枪打中的气球的颜色,0表示没打中任何颜色的气球。

输出格式

就一个整数,表示游客打爆所有颜色气球用的最少枪数。如果游客无法在这n枪打爆所有颜色的气球,则输出-1

样例

样例1

样例输入1

12 5
2 5 3 1 3 2 4 1 0 5 4 3

样例输出1

6

样例2

样例输入2

14 5
2 5 3 1 3 2 4 1 0 5 4 3 2 1

样例输出2

5

提示

30% n<=1000 m<=20。
100% n<=1000000 m<=2000。
 
样例1解释:有五种颜色的气球,编号1到5。游客从第2枪开始直到第7枪,这连续六枪打爆了 5 3 1 3 2 4这几种颜色的气球,包含了从1到5所有的颜色,所以最少枪数为6。

题解

首先,暴力求出第一个符合区间:

bool f=1;
ll n,m;
cin>>n>>m;
for(int i=0;i<n;i++)
{
	cin>>e[i];
	if(f&&(!bound(book,1,m+1,0)))
		_min=tail=i+1,f=0;
}

接着,用队列,像车轮一样轧过去,队首出现在队中就head++

while(tail<n)
{
	tail++;
	while((e[head]==0)||bound(e,head+1,tail,e[head]))
			head++;
	if(tail-head<_min)
		_min=tail-head;
}

最后:

cout<<_min;
return 0;

b u t . . . . . . but......

Time Limit Exceeded (10)
呃……晕_(¦3」∠)_
经过分析,我们发现时间主要耗在bound上:

bool bound(ll e[],ll start,ll end,ll x)
{
	for(ll i=start;i<end;i++)
		if(e[i]==x)
			return 1;
	return 0;
}

如果建立一个表,查表不就快许多了吗?
前面那个book不就是吗?
于是乎……改了改:

while(tail<=n)
{		
	while(e[head]==0||book[e[head]]>1)
		book[e[head]]--,head++;
	if(tail-head<_min)
		_min=tail-head;
	book[e[tail]]++;
	tail++;
}

最后,特判没有任何区间:

if(f)
{
	cout<<-1;
	return 0;
}

代码

#include<iostream>
#define INT_MAX 2147483647
using namespace std;
typedef long long ll;
ll e[1000001],book[1000001],head,tail,_min=INT_MAX;
bool f=1;
bool bound(ll f[],ll start,ll end,ll x)
{
	for(ll i=start;i<end;i++)
		if(f[i]==x)
			return 1;
	return 0;
}
int main()
{
	ll n,m;
	cin>>n>>m;
	for(int i=0;i<n;i++)
	{
		cin>>e[i];
		if(f)
			book[e[i]]++;
		if(f&&(!bound(book,1,m+1,0)))
			_min=tail=i+1,f=0;
	}
	if(f)
	{
		cout<<-1;
		return 0;
	}
	while(tail<=n)
	{		
		while(e[head]==0||book[e[head]]>1)
			book[e[head]]--,head++;
		if(tail-head<_min)
			_min=tail-head;
		book[e[tail]]++;
		tail++;
	}
	cout<<_min;
	return 0;
}

a t l a s t : at\,last:

Accepted (100)
完结撒花!

发布了2 篇原创文章 · 获赞 1 · 访问量 32

猜你喜欢

转载自blog.csdn.net/liangyingswu/article/details/105471340
今日推荐