Snow Boots I

Snow Boots I

时间限制: 1 Sec   内存限制: 128 MB
提交: 6   解决: 3
[ 提交][ 状态][ 讨论版][命题人: admin]

题目描述

It's winter on the farm, and that means snow! There are N tiles on the path from the farmhouse to the barn, conveniently numbered 1…N, and tile i is covered in fi feet of snow.
In his farmhouse cellar, Farmer John has B pairs of boots, numbered 1…B. Some pairs are more heavy-duty than others, and some pairs are more agile than others. In particular, pair i lets FJ step in snow at most sisi feet deep, and lets FJ move at most didi forward in each step.

Farmer John starts off on tile 1 and must reach tile N to wake up the cows. Tile 11 is sheltered by the farmhouse roof, and tile N is sheltered by the barn roof, so neither of these tiles has any snow. Help Farmer John determine which pairs of snow boots will allow him to make the trek.

输入

The first line contains two space-separated integers N and B (1≤N,B≤105).
The second line contains N space-separated integers; the ith integer is fi, the depth of snow on tile i (0≤fi≤109). It's guaranteed that f1=f,N=0.
The next B lines contain two space-separated integers each. The first integer on line i+2 is sisi, the maximum depth of snow in which pair i can step. The second integer on line i+2 is di, the maximum step size for pair i. It's guaranteed that 0≤si≤109 and 1≤di≤N−1.

输出

The output should consist of B lines. Line i should contain a single integer: 1 if Farmer John can trek from tile 1 to tile N wearing the iith pair of boots, and 0 otherwise.

样例输入

8 7

0 3 8 5 6 9 0 0

0 5

0 6
6 2
8 1
10 1

5 3
150 7

样例输出

0
1
1
0

1
1

1

好难理解的英语,大意就是有n块瓦片,每一个瓦片都有一个雪的深度,第一片跟最后一片的雪深度是0. 现在有m双靴子,每一双靴子都有一个最大能经过的积雪数量和最远能跨越的瓦片数,问每一双靴子是否都能从1走到n,输出0或1.

首先容易确定的是当这双靴子能踏过的雪的深度大于等于最深的雪的深度的时候,就一定能走到最后。然后正常模拟是n*m,想办法降低一维的复杂度。不难发现,瓦片雪的厚度这一维的时间可以优化掉,当瓦片的雪有序时,令靴子能踏过雪的深度也有序,两者都从大往小跑,把大于这双靴子的瓦片的雪的厚度都减去,这样一定能走到最后,但需要求去掉这个瓦片后的瓦片距离,并保留一个maxx值,判断maxx是否大于他能跨过的宽度。

这样的话可以用两个数组模拟指针,会容易发现由于靴子踏雪的高度递减,瓦片的雪只需要从n遍历到1,然后maxx的值也是在不断的增大,这样再去用一个数组接受答案,最后输出。写代码10分钟,思考两小时。

代码实现:

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<vector>
#include<set>
#include<cstdio>
#define ll long long
#define mset(a,x) memset(a,x,sizeof(a))

using namespace std;
const double PI=acos(-1);
const int inf=0x3f3f3f3f;
const double esp=1e-6;
const int maxn=1e6+5;
const int mod=1e9+7;
int dir[4][2]={0,1,1,0,0,-1,-1,0};
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
ll inv(ll b){if(b==1)return 1; return (mod-mod/b)*inv(mod%b)%mod;}
ll fpow(ll n,ll k){ll r=1;for(;k;k>>=1){if(k&1)r=r*n%mod;n=n*n%mod;}return r;}
ll Fpow(ll n,ll k){ll r=1;for(;k;k>>=1){if(k&1)r=r*n;n=n*n;}return r;}
ll upd(ll x,ll v){x=x+v>=mod?x+v-mod:x+v;return x;}
int a[maxn],b[maxn],c[maxn],index1[maxn],index2[maxn];
int pre[maxn],nxt[maxn],ans[maxn];

int cmp1(int x,int y)
{
	return a[x]<a[y];
}

int cmp2(int x,int y)
{
	return b[x]<b[y];
}

int main()
{
	int n,m,i,j,k;
	scanf("%d%d",&n,&m);
	for(i=1;i<=n;i++)
	{
		scanf("%d",&a[i]);
		index1[i]=i;
	}
	
	for(i=1;i<=m;i++)
	{
		scanf("%d%d",&b[i],&c[i]);
		index2[i]=i;
	}
	sort(index1+1,index1+1+n,cmp1);
	sort(index2+1,index2+1+m,cmp2);
	for(i=0;i<=n;i++)        //默认后继前驱 
	{
		pre[i]=i-1;
		nxt[i]=i+1;
	}
	int t=n,maxx=1;         //t记录瓦片移动,maxx记录最大步数
	for(i=m;i>0;i--)
	{
		int s=index2[i];   //找到鞋子在原数组中的坐标
		while(t>0&&a[index1[t]]>b[s]) 
		{
			int c=index1[t];      //当前瓦片的位置,删除 
			nxt[pre[c]]=nxt[c];   //前驱的后继变成他的后继 
			pre[nxt[c]]=pre[c];   //后继的前驱变成他的前驱 
			maxx=max(maxx,nxt[c]-pre[c]);
			t--; 
		}
		if(c[s]>=maxx)
		ans[s]=1;
		else
		ans[s]=0;
	}
	for(i=1;i<=m;i++)
	printf("%d\n",ans[i]);
}
/*
7 3
0 9 8 0 8 9 0
7 3
8 2
10 1
*/ 

转载于:https://www.cnblogs.com/buzaijian/p/8849167.html

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值