传送点:http://acm.hdu.edu.cn/showproblem.php?pid=2155
N个平台(L,R,H) 起点(X,Y)最高
问能否在M时间内落到地面(高度0)每次下落高度小于等于MAX#落到地面输出NO,落不到YES
先对所有的排序,然后从1——N逐个处理出到达左端点最短时间 le[i] 和右端点最短时间 ri[i]
最后计算出到达地板的最小时间minTime和m对比。
/*
1 hdu 2155
2 2014/11/1
3 Ouc_Sky
4 N个平台(L,R,H) 起点(X,Y)最高
问能否在M时间内落到地面(高度0)每次下落高度小于等于MAX
#落到地面输出NO,落不到YES
0<T<=10组数据 0<H[i]<1000 0<X<=1000 0<N<=1000
*/
#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;
const int maxn = 1010;
struct node
{
int l,r,h;
}p[maxn];
int le[maxn];
int ri[maxn];
int cmp(node a, node b) {return a.h>b.h;}
int main()
{
int t;
scanf("%d", &t);
while(t--)
{
int n,x,y,maxx,m;
int minTime = 0x3f3f3f3f;
memset(le,0x3f3f3f3f,sizeof(le));
memset(ri,0x3f3f3f3f,sizeof(ri));
scanf("%d %d %d %d %d", &n, &x, &y, &maxx, &m);
for (int i = 1; i <= n; i ++ )
scanf("%d %d %d", &p[i].l, &p[i].r, &p[i].h);
p[0].l = p[0].r = x;
p[0].h = y;
p[n+1].l = 0;
p[n+1].r = 1001;
p[n+1].h = 0;/*构造地面*/
le[0] = 0;
ri[0] = 0;
sort(p, p+n+1, cmp);
for (int i = 0; i <= n; i ++ )
{
for(int j = i+1; j <= n+1; j ++ )
{
if (p[i].h - p[j].h > maxx) break;
if (p[j].l <= p[i].l && p[i].l <= p[j].r) /*从左侧掉下去*/
{
if (j == n+1) /*到达地板*/
{
minTime = min(minTime, le[i] + (p[i].h - p[j].h));
break;
}
le[j] = min(le[j], le[i] + (p[i].h - p[j].h) + (p[i].l - p[j].l));
ri[j] = min(ri[j], le[i] + (p[i].h - p[j].h) + (p[j].r - p[i].l));
break;
}
}
for (int j = i+1; j <= n+1; j ++ )
{
if (p[i].h - p[j].h > maxx) break;
if (p[j].l <= p[i].r && p[i].r <= p[j].r) /*从右侧掉下去*/
{
if (j == n+1) /*到达地板*/
{
minTime = min(minTime, ri[i] + (p[i].h - p[j].h));
break;
}
le[j] = min(le[j], ri[i] + (p[i].h - p[j].h) + (p[i].r - p[j].l));
ri[j] = min(ri[j], ri[i] + (p[i].h - p[j].h) + (p[j].r - p[i].r));
break;
}
}
}
//printf("%d\n",minTime);
if (minTime <= m)
printf("NO\n");
else
printf("YES\n");
}
return 0;
}