问题描述
"Help Jimmy" 是在下图所示的场景上完成的游戏:
场景中包括多个长度和高度各不相同的平台。地面是最低的平台,高度为零,长度无限。
Jimmy 老鼠在时刻0 从高于所有平台的某处开始下落,它的下落速度始终为1 米/秒。
当Jimmy 落到某个平台上时,游戏者选择让它向左还是向右跑,它跑动的速度也是1 米/秒。
当Jimmy 跑到平台的边缘时,开始继续下落。Jimmy 每次下落的高度不能超过MAX 米,不
然就会摔死,游戏也会结束。
设计一个程序,计算Jimmy 到地面时可能的最早时间。
输入数据
第一行是测试数据的组数 t(0 <= t <= 20)。每组测试数据的第一行是四个整数N,X,
Y,MAX,用空格分隔。N 是平台的数目(不包括地面),X 和Y 是Jimmy 开始下落的位置
的横竖坐标,MAX 是一次下落的最大高度。接下来的N 行每行描述一个平台,包括三个整
数,X1[i],X2[i]和H[i]。H[i]表示平台的高度,X1[i]和X2[i]表示平台左右端点的横坐标。1
<= N <= 1000,-20000 <= X, X1[i], X2[i] <= 20000,0 < H[i] < Y <= 20000(i = 1..N)。所有坐
标的单位都是米。
Jimmy 的大小和平台的厚度均忽略不计。如果Jimmy 恰好落在某个平台的边缘,被视
为落在平台上。所有的平台均不重叠或相连。测试数据保Jimmy 一定能安全到达地面。
输出要求
对输入的每组测试数据,输出一个整数,Jimmy 到地面时可能的最早时间。
输入样例
1
3 8 17 20
0 10 8
0 10 13
4 14 3
输出样例
23
思路:
用一棵树形保存每一个平台,然后递归求解
#include <stdio.h>
#include <stdlib.h>
struct Line
{
int x1;
int x2;
int h;
Line * Parent;
Line * Left;
Line * Right;
};
Line *line;
int cmp(const void * a,const void * b)
{
Line *m,*n;
m=(Line *)a;
n=(Line *)b;
if(m->h>n->h)
return -1;
else if(m->h==n->h)
{
if(m->x1>n->x1)
return -1;
else return 1;
}else
{
return 1;
}
}
void tree(Line * lp,int i,int n,int max)
{
if(i+1<n-1)
{
if(lp[i].x2>=lp[i+1].x2)
{
lp[i].Left=&lp[i+1];
tree(lp,i+1,n,max);
if(i+2<n-1)
{
for(int k=i+2;k<n;k++)
{
if(lp[i].h-lp[k].h<=max)
{
if(k==n-1)
{
lp[i].Right=&lp[k];
tree(lp,k,n,max);
break;
}
else if(lp[i].x1<=lp[k].x1)
{
lp[i].Right=&lp[k];
tree(lp,k,n,max);
break;
}else {}
}else
{
lp[i].Right=NULL;
break;
}
}//for
}else
{
lp[i].Right=&lp[n];
}
}else
{
lp[i].Right=&lp[i+1];
tree(lp,i+1,n,max);
for(int k=i+2;k<n;k++)
{
if(lp[i].h-lp[k].h<=max)
{
if(k==n-1)
{
lp[i].Left=&lp[k];
tree(lp,k,n,max);
break;
}
else if(lp[i].x2>=lp[k].x2)
{
lp[i].Left=&lp[k];
tree(lp,k,n,max);
break;
}else{}
}else
{
lp[i].Left=NULL;
break;
}
}//for
}
}
else
{
lp[i].Left=&lp[n];
lp[i].Right=&lp[n];
}
}
int min(int a,int b)
{
if(a<b)
return a;
else return b;
}
int cal(Line * lp,int x)
{
if(lp->Left==lp->Right)
{
return min(lp->x2-x,x-lp->x1);
}
if(lp==NULL)
return 10000000;
return min(x-lp->x1+cal(lp->Left,lp->x1),lp->x2-x+cal(lp->Right,lp->x2));
}
int main()
{
int t;
scanf("%d",&t);
for(int i=0;i<t;i++)
{
int n,x,y,max;
int res=0;
scanf("%d%d%d%d",&n,&x,&y,&max);
line=new Line[n+1];
for(int i=0;i<n;i++)
{
scanf("%d%d%d",&line[i].x1,&line[i].x2,&line[i].h);
}//read items
line[n].h=0;
line[n].x1=0;
line[n].x2=200000000;
qsort(line,n+1,sizeof(Line),cmp);//sort items by hight
tree(line,0,n+1,max);
res=y+cal(line,x);
/*for(int i=0;i<n;i++)
{
printf("line %d\nx1=%d x2=%d h=%d \n",i,line[i].x1,line[i].x2,line[i].h);
}*/
printf("%d\n",res);
delete []line;
}
}