oj 1027

空管调度算法挑战

1027. 戴绿帽子的空管

Description

幽会计划

二哥如今在TNCM机场做空管。二哥不幸被分配到了进近席,进近席位要负责处理所有准备降落在机场的飞机,让他们平稳地落在跑道上。飞机降落一般遵循五边进近航图,不过在这道题目中你不需要关心什么是五边进近,只要看下面这张图。

一架飞机总是从下滑道入口(A点)开始接受二哥管制,直到降落成功(B点)。飞机不会是同一型号的,速度也不一样,所以从A点到B点所需的时间不同。二哥得小心一点,不能把事情搞砸了:(1)下滑道内不允许飞机互相超越;(2)一架飞机降落之后,至少要等待一段时间才允许下一架飞机降落(即到达B的时间间隔要大于等于一个值)。

二哥是个聪明的人,他写了一个程序来帮他控制所有飞机,然后他就可以喝茶去了。二哥的策略是:通过拒绝某些飞机进入下滑道,来保证下滑道上的飞机永远不会距离太近。也就是说,只要飞机被允许进入下滑道,就可以安全降落。

每当一架飞机来到下滑道的入口时,二哥的程序就会判断:如果允许这架飞机进入下滑道,它能否安全降落。如果能安全降落,二哥就允许他进入下滑道,否则二哥会立即要求这架飞机在A点复飞。

原则上,两架飞机不应该同时出现在A点,但这种情况显然可能出现。如果真的出现了这种情况,则说明空管局这次彻底把事情搞砸,二哥的策略显然可能是诱因。

简单来说,在未来的一段时间内,共有N架飞机要降落,他们会在Ti时刻首次出现在下滑道入口,他们从A点到B点需要的时间为Ui。如果他们被二哥命令在A点复飞,他们会在Gi分钟后再次出现在下滑道入口。飞机的安全降落间隔是S。

现在,二哥的女朋友找到你,请你计算一下每架飞机会在第几分钟完成降落。这样她可以估算出二哥什么时候下班,以便瞒着二哥去和情人去幽会。

Input Format

第一行有三个正整数N、MAX、S,表示有多少飞机,最长模拟的时间,以及安全降落时间间隔。

之后有N行,每行有三个非负整数,依次为Ti、Ui、Gi,分别表示第i架飞机的首次到达时间、从A点到B点耗时、复飞耗时。

N≤1000N≤1000 MAX≤1000000MAX≤1000000 S≤1000S≤1000 Ti≤1000000Ti≤1000000 ,Ui≤1000Ui≤1000 ,Gi≤1000Gi≤1000

Output Format

假设在MAX时刻之前([0..MAX-1]),有飞机同时出现在了下滑道口,则输出“CHANGE BOYFRIEND”,因为飞机撞了,三哥估计要下岗了,她可以换一个男朋友了。

假设在MAX时刻之前没有飞机相撞,但模拟结束后仍然有飞机没有降落,则输出一行“GO DATING”,以表示三哥的女朋友可以放心大胆地幽会去了。

否则输出N行,每行一个整数,表示第i架飞机最终降落的时刻。

Sample Input

4 20 2
0 2 5
1 2 1
5 2 1
6 10 10

Sample Output

2
4
7
16

Sample Input

3 10 2
0 2 5
1 2 3
4 1 1

Sample Output

CHANGE BOYFRIEND

样例解释

分析:

0时刻,第一架飞机到达A,二哥允许他进入下滑道,在第2时刻降落。

1时刻,第二架飞机到达A,二哥要求他复飞,因为降落间距小于安全标准。

2时刻,第二架飞机复飞后再次回到A,二哥允许他进入下滑道,在第4时刻降落。

5时刻,第三架飞机到达A,二哥允许他进入下滑道,在第7时刻降落

6时刻,第四架飞机到达A,二哥允许他降落,在第16时刻降落。


分析:

在4时刻,第二架飞机和第三架飞机会相撞。

 

 

#include <iostream>
#include <malloc.h>
using namespace std;
typedef struct plane{
    int id,Ti,Ui,Gi,rest,flag,out;
}; 
void updateTime(plane *pl,int &t){
    for(int j=0 ; pl[j].flag != 0 ; ++j){
        if( pl[j].flag==1){
            pl[j].rest--;
            if( pl[j].rest == 0){
                pl[j].out = t;
                pl[j].flag= 2;
            }
        }
    }
}
int findPlane(int t,int N,plane *pl){     //-1撞机,0没飞机,其他返回飞机id,
    bool flag = true;
    int i=0;
    while(i<N){
        if(pl[i].Ti == t){
            flag = false;
            break;
        }
        ++i;
    }
    if(!flag){
        for(int j=i+1;j<N;++j){
            if(pl[i].Ti == pl[j].Ti)
                return -1;
        }    
    }
    if(!flag){
        return i;
    }else{
        return 0;    
    }
}

int main(){
    int N,MAX,S;
    cin>>N>>MAX>>S;
    plane *pl;
    pl = (plane*)malloc(N * sizeof(plane));
    int *flag = new int[N];//0未入,1入,2结束 
    for(int i=0;i<N;++i){
        cin>>pl[i].Ti>>pl[i].Ui>>pl[i].Gi;
        pl[i].rest = pl[i].Ui;
        pl[i].flag = 0;
        pl[i].out = 0;
    }
    pl[0].flag = 1;
    int last = pl[0].Ui;
    
    for(int t=pl[0].Ti; t<=MAX ; ++t){
        //cout<<t<<": ";
        if( findPlane(t,N,pl) == -1 ){     //撞机 
            cout<<"CHANGE BOYFRIEND";
            return 0; 
        }else if( findPlane(t,N,pl) == 0){       //没有飞机
            //cout<<"无";
            updateTime(pl,t);
            if(last>0)
                last--;
        }else{
            if( pl[findPlane(t,N,pl)].Ui - last >= S || last == 0){//放入 ,如果A到B没有飞机,准入
                //cout<<"放入";
                last = pl[findPlane(t,N,pl)].Ui-1;
                pl[findPlane(t,N,pl)].flag = 1;
            }else{                              //复飞 
                //cout<<"复飞:";
                pl[findPlane(t,N,pl)].Ti += pl[findPlane(t,N,pl)].Gi;
                if(last>0)
                    last--;
            }
            updateTime(pl,t);
        }
        //cout<<last<<endl;
    }
    
    if( pl[N-1].out == 0 || pl[N-1].out +1 > MAX  ){
        cout<<"GO DATING"<<endl;
    }else{
        for(int j=0;j<N;++j){
            cout<<pl[j].out+1<<endl;    
        }    
    }
    return 0;

 

 

2019 3-5 结果还是有WA -   。 -

2019 3-6 GO DATING 和CHANGE BOYFRIEND都没问题了,按时完成任务结果输出还是有问题

网上找到一个解决方案可以A,但用下面 10 50 5的数据好像有问题。

#include <iostream>
#include <vector>
#include <algorithm>
#include <map>

using namespace std;

class Fly{
public:
    int id,in,out,repStay;
    Fly(int fid,int a, int b, int c){
        id = fid;
        in = a;
        out = b;
        repStay = c;
    }
    Fly(){};
};


int main()
{
    int n,Max,s,N;
    cin>>n>>Max>>s;
    N = n;
    map<int, Fly> fly;
    int fid = 0;
    while(n-->0){
        int in,out,repStay;
        cin>>in>>out>>repStay;
        fly[in] = Fly(fid,in,out,repStay);
        fid++;
    }
    int res[N];
    map<int, Fly>::iterator iter = fly.begin();
    int lastLoad = iter->second.in + iter->second.out;
    iter++;
    res[0] = lastLoad;
    while(iter != fly.end()){
        if(iter->second.in>=Max){
            cout<<"GO DATING";
            return 0;
        }
        int achi = iter->second.in + iter->second.out;
        if(achi-lastLoad>=s){
            res[iter->second.id] = achi;
            lastLoad = achi;
        }else{
            int n_in = iter->second.in + iter->second.repStay;
            if(fly.count(n_in)>0){
                cout<<"CHANGE BOYFRIEND";
                return 0;
            }else{
                fly[n_in] = Fly(iter->second.id, n_in, iter->second.out, iter->second.repStay);
            }
        }
        iter++;
    }
    for(int i=0;i<N;i++)
        cout<<res[i]<<" "<<endl;
    return 0;
}

 

左边是找的,在代码判断复飞和放入滑道处加上了标识显示输出。可以看到3时刻的情况为:

第1架飞机于2时刻到达B点,第2架飞机于第3时刻到达,应该执行的是放入操作而不是复飞。原题应该是没有考虑到安全时间S大于飞机在A到B滑行时间的情况。(就像此处的S > Ui, S=5,Ui = 2),导致Ti + Ui - lastLoad < S。

所以如果测试数据有这种情况,在A到B空闲时,滑行时间Ui长于安全时间S怎么也不会准入。

8 30 3
0 3 1
2 4 2
4 2 1
7 5 4
10 8 5
15 4 4
18 5 3
21 2 2 

10 50 5
0 2 1
3 2 5
4 2 2
7 5 5
10 2 3
15 7 7
23 5 4
32 8 4
38 7 5
42 3 3

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值