dpl[i]=x 表示到达第 i 个阶梯的左端点需要的最少时间,dpr[i]=x 相应的久是到达第 i 个阶梯的右端点所需要的最少时间,对于第 i 个阶梯,往下搜寻距离在Max之内的阶梯,假设找到阶梯 j ,阶梯 j 可以使接住从阶梯 i 左端点跳下的人 ,那么到达阶梯 j 左端点的最短时间就是 dpl[j]=min(dpl[j] , 高度差加上走到 j 左端点的距离)
dpr 也是一样的,每个阶梯的左端点和右端点都只能下落一次,假设左端点的被接住了,右端点的还没有,那么搜索的时候就要注意设置标记,不再进入左端点更新,起始位置和终点都要当做阶梯加入数组,还要遍历一遍找到起始位置,不保证起始位置是在最顶端。
#include <algorithm>
#include <iostream>
#include <stdio.h>
#include <string>
#include <cstring>
#include <vector>
#include <set>
#include <math.h>
#define eps 1e-14
#define pi acos(-1)
#define ll long long
#define RD T*(rand()*2-RAND_MAX)
#define Drand (long double)rand()/RAND_MAX
#define LINF 0x7f7f7f7f7f7f7f7f
#define INF 0x3f3f3f3f
using namespace std;
const int maxn=1005;
const long long mod=1e18;
ll MOD(ll a,ll m){return a>m?a%m+m:a;}
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
int dpl[1005],dpr[1005];
struct nn
{
int x1,x2,h;
}bk[maxn];
int cmp(nn a,nn b)
{
return a.h>b.h;
}
int main()
{
// freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
int t;
int n,x,y,Max;
scanf("%d",&t);
while(t--){
memset(dpl,INF,sizeof dpl);
memset(dpr,INF,sizeof dpr);
scanf("%d%d%d%d",&n,&x,&y,&Max);
for(int i=1;i<=n;i++)scanf("%d%d%d",&bk[i].x1,&bk[i].x2,&bk[i].h);
n++;
bk[n].x1=bk[n].x2=x;
bk[n].h=y;
n++;
bk[n].x1=-50000;
bk[n].x2=50000;
bk[n].h=0;
sort(bk+1,bk+1+n,cmp);
int st=1;
for(int i=1;i<=n;i++){
if(bk[i].x1==bk[i].x2 && bk[i].x2==x && bk[i].h==y){
st=i;
break;
}
}
dpl[st]=0;
dpr[st]=0;
for(int i=st;i<=n;i++){
int l=0,r=0;
for(int j=i+1;j<=n;j++){
if(bk[i].h-bk[j].h>Max)break;//too height
if(bk[j].h==bk[i].h)continue;//euqal height
if(l==1 && r==1)break;//can not down
if(bk[j].x1<=bk[i].x1 && bk[i].x1<=bk[j].x2 && l==0){//can go left
int costl=(bk[i].h-bk[j].h) + dpl[i] + (bk[i].x1-bk[j].x1);
int costr=(bk[i].h-bk[j].h) + dpl[i] + (bk[j].x2-bk[i].x1);
if(j==n){
costl=bk[i].h-bk[j].h+dpl[i];
costr=INF;
}
dpl[j]=min(dpl[j],costl);
dpr[j]=min(dpr[j],costr);
l=1;
}
if(bk[j].x1<=bk[i].x2 && bk[i].x2<=bk[j].x2 && r==0){//can go right
int costl=dpr[i] + (bk[i].h-bk[j].h) + (bk[i].x2-bk[j].x1);
int costr=dpr[i] + (bk[i].h-bk[j].h) + (bk[j].x2-bk[i].x2);
if(j==n){
costl=INF;
costr=bk[i].h-bk[j].h + dpr[i];
}
dpl[j]=min(dpl[j],costl);
dpr[j]=min(dpr[j],costr);
r=1;
}
}
}
// for(int i=1;i<=n;i++){
// cout<<"i = "<<i<<" dpl="<<dpl[i]<<" dpr="<<dpr[i]<<" x1="<<bk[i].x1<<" x2="<<bk[i].x2
// <<" h="<<bk[i].h<<endl;
// }
printf("%d\n",min(dpl[n],dpr[n]));
}
return 0;
}