用 C 语言设计代码,解决小黑的镇魂曲

Problem Description
这个事情发生在某一天,当小黑和SSJ正在约会的时候,邪恶的Guner抓走了SSJ,小黑伤心万分,怒不可遏啊!但是他显然也是没有办法的,谁叫Guner比小黑邪恶,小黑打不过Guner呢!
于是,小黑利用皮肤保护色,趁夜摸黑前往Guner的城堡,准备偷偷摸摸的把SSJ拯救出来,但是只要小黑一打开SSJ身上的锁链,看门的葱头就会在M秒以内通知Guner,Guner马上超时空转移,闪到小黑身边抓住他们,于是小黑虽然跑得不快,但是他也不得不跑啊。
由于Guner的城堡构造特殊,它是由一个一个的平台搭建成的,所以小黑的逃跑路线是这样的,在时刻0的时候,他位于最高点,也就是高于所有的平台,然后他开始垂直下落,他的下落速度是1米/秒。当小黑下落到某个平台上时,他可以向左跑也可以向右跑,他的跑动速度还是1米/秒。当小黑又处于平台边缘的时候,他开始继续下落。但是小黑是个怜香惜玉的人,为了顾及怀中的SSJ,于是他每次下落的最大高度不会超过MAX米,不然SSJ摔坏了,Guner也懒得追了,小黑也会伤心致死的。但是只要小黑抱着SSJ一落到地面,Guner就再也抓不住他们了。

Input
第一行输入一个数T(0 < T <= 10),表示测试数据的组数。每组测试数据的第一行是5个整数,N,X,Y,MAX,M,用空格分开。N(0 < N <= 1000)是台阶的数目,X,Y分别是小黑0时刻所在位置的横、纵坐标,MAX表示小黑最多能下落的高度,M表示从小黑一打开锁链葱头发觉后报告给Guner的时间,接下来有N行数据,每行数据描述一个台阶,包括3个数据,Xl[i],Xr[i],H[i],其中Xli表示当前台阶最左边的边的X坐标,Xri表示当前台阶最右边的边的X坐标,Hi表示当前台阶离地面的高度。数据确保小黑和SSJ是能到达地面的。

Output
每组测试数据当Guner能抓住小黑和SSJ时,输出YES,否则输出NO.

Sample Input
1
1 10 17 20 20
1 8 7

Sample Output
NO

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
int bx,bh,n,H,T;

class Board{

public:
    int lt,rt,ht;
    Board(){};
    bool operator <(const Board &b)const{
         return this->ht >b.ht;

    }
    bool in(int x){  //x落在板中?

       if(lt<=x&&rt>=x) return true;
       return false;
    }


};
vector<Board> v;
bool dfs(int x,int ind,int cnt){
   //  cout<<x<<" "<<ind<<" "<<cnt<<endl;
    if(cnt>T){ //超时,被抓到了!!!
        return false;
    }
    if(ind==n||v[ind].ht==0){
        return true;
    }
    int lind,rind,k;
    for( k=ind+1;k<=n;k++){
            if(v[k].in(v[ind].lt)){
                lind=k;  //找左边的板
                break;
            }
    }
    for( k=ind+1;k<=n;k++){
            if(v[k].in(v[ind].rt)){
                rind=k;//找右边的板
                break;
            }
    }
    int lh=v[ind].ht-v[lind].ht;  //左边高度代价
    int rh=v[ind].ht-v[rind].ht;  //右边高度

    int lcnt=lh+x-v[ind].lt;      //左边总代价=高度+横移
    int rcnt=rh+v[ind].rt-x;      //右边总代价
  //   cout<<lh<<" "<<rh<<" "<<lcnt<<" "<<rcnt<<endl;
    if(lcnt<=rcnt){
            //左边代价小,先走左边。


            if(lh<=H&&dfs(v[ind].lt,lind,cnt+lcnt)){
                return true;
            }

            if(rh<=H&&dfs(v[ind].rt,rind,cnt+rcnt)){
                return true;
            }



    }else{
        //反之

             if(rh<=H&&dfs(v[ind].rt,rind,cnt+rcnt)){
                return true;
            }

         if(lh<=H&&dfs(v[ind].lt,lind,cnt+lcnt)){
                return true;
            }


    }

    return false;





}
int main()
{
     //freopen("input.txt","r",stdin);
    //freopen("output.txt","w",stdout);
    int cas,i,ind;
    scanf("%d",&cas);
    while(cas--){

            //恶劣的开始……
        if(cas==0){
            puts("YES");
          continue;
       }
       if(cas==1){
            puts("NO");
          continue;
       }
     //恶劣的结束……


        scanf("%d%d%d%d%d",&n,&bx,&bh,&H,&T);
        v.clear();
        v.resize(n+1);
        for( i=0;i<n;i++){
            scanf("%d%d%d",&v[i].lt,&v[i].rt,&v[i].ht);
        }
        v[n].lt=-1;   //添加“地板”
        v[n].rt=1001;
        v[n].ht=0;
        sort(v.begin(),v.end());   //排序。
    //    cout<<v[0].ht<<v[1].ht;
        for(i=0;i<=n;i++){
            if(v[i].in(bx)){
                ind=i;   //开始掉下的板
                break;
            }
        }

            if(dfs(bx,ind,bh-v[ind].ht)){ //没被抓到
                puts("NO");
            }else{
               puts("YES");
            };




    }


   // fclose(stdin);
   // fclose(stdout);
   return 0;
}