Help Jimmy
"Help Jimmy" 是在下图所示的场景上完成的游戏。
场景中包括多个长度和高度各不相同的平台。地面是最低的平台,高度为零,长度无限。
Jimmy老鼠在时刻0从高于所有平台的某处开始下落,它的下落速度始终为1米/秒。当Jimmy落到某个平台上时,游戏者选择让它向左还是向右跑,它跑动的速度也是1米/秒。当Jimmy跑到平台的边缘时,开始继续下落。Jimmy每次下落的高度不能超过MAX米,不然就会摔死,游戏也会结束。
设计一个程序,计算Jimmy到底地面时可能的最早时间。
Input
场景中包括多个长度和高度各不相同的平台。地面是最低的平台,高度为零,长度无限。
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恰好落在某个平台的边缘,被视为落在平台上。所有的平台均不重叠或相连。测试数据保证问题一定有解。
Output
Jimmy的大小和平台的厚度均忽略不计。如果Jimmy恰好落在某个平台的边缘,被视为落在平台上。所有的平台均不重叠或相连。测试数据保证问题一定有解。
对输入的每组测试数据,输出一个整数,Jimmy到底地面时可能的最早时间。
Sample Input
1 3 8 17 20 0 10 8 0 10 13 4 14 3Sample Output
23
这题好坑了,一直wr、wr、wr
#include<stdio.h> #include<iostream> #include<algorithm> #include<string.h> using namespace std; #define oo 30000000 int n,q,w,m; int dp[1010][2]; struct stu{ int l; int r; int h; }st[1010]; bool cmp(stu i,stu j) { if(i.h<j.h) return false; return true; } int dfs(int l,bool f) { int t=n+5; int y=st[l].h; int x; if(f) x=st[l].l; else x=st[l].r; for(int i=l+1;i<=n;i++) { if(st[i].l<=x&&st[i].r>=x) { t=i; break; } } if(t<=n)//t一定要赋个初值 { if(y-st[t].h>m) return oo; } else { if(y>m) return oo; else return y; } int nl=x-st[t].l+y-st[t].h; int nr=st[t].r-x+y-st[t].h; if(dp[t][0]==-1) dp[t][0]=dfs(t,true); if(dp[t][1]==-1) dp[t][1]=dfs(t,false); nl+=dp[t][0]; nr+=dp[t][1]; if(nl<nr) return nl; return nr; } /* 1 10 899 52 50 893 903 18 890 900 38 898 908 8 910 920 8 894 904 43 881 891 18 872 882 38 867 877 43 842 852 43 895 905 3 61 */ int main() { int T; cin>>T; while(T--) { stu b[1010]; memset(dp,-1,sizeof(dp)); cin>>n>>q>>w>>m; st[0].l=q; st[0].r=q; st[0].h=w; for(int i=1;i<=n;i++) { cin>>st[i].l>>st[i].r>>st[i].h; if(st[i].l>st[i].r) swap(st[i].l,st[i].r); } sort(st,st+n+1,cmp);//这里坑了好久。。。忘记是从1开始的 /* printf("\n\n"); for(int i=1;i<=n;i++) printf("%d %d %d\n",st[i].l,st[i].r,st[i].h);*/ int s=1; int x=st[1].l,y=st[1].r,t=st[1].h; b[1].h=t; b[1].l=x; b[1].r=y; //相同高度而且有重叠部分的合并在一起,没重叠就分开算 for(int i=2;i<=n;i++) { if(t==st[i].h&&((x>=st[i].l&&x<=st[i].r)||(y>=st[i].l&&y<=st[i].r) ||(st[i].l>=x&&st[i].l<=y)||(st[i].r>=x&&st[i].r<=y))) { x=min(x,st[i].l); y=max(y,st[i].r); } else { b[s].h=t; b[s].l=x; b[s].r=y; t=st[i].h; x=st[i].l; y=st[i].r; s++; b[s].h=t; b[s].l=x; b[s].r=y; } } n=s; for(int i=1;i<=s;i++) { st[i].l=b[i].l; st[i].r=b[i].r; st[i].h=b[i].h; } /* printf("\n\n"); for(int i=1;i<=n;i++) printf("%d %d %d\n",st[i].l,st[i].r,st[i].h);*/ cout<<dfs(0,false)<<endl; } return 0; }