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>
using namespace std;
int main(){
    int N,MAX,S;
    cin>>N>>MAX>>S;
    int Ti[N],Ui[N],Gi[N],rest[N],out[N];;
    int flag[N];//0未入,1入,2结束 
    for(int i=0;i<N;++i){
        cin>>Ti[i]>>Ui[i]>>Gi[i];
        rest[i] = Ui[i];
        flag[i] = 0;
        out[i] = 0;
    }
    int time;              //复飞剩余 
    bool flag1=false;       //是否等待 
    bool flag2=true;
    flag[0] = 1;
    int i=1;
    for(int t=Ti[0]; t<=MAX ; ++t){
        if(i == N){
            for(int j=0 ; flag[j] != 0 ; ++j){
                if(flag[j]==1){
                    rest[j]--;
                    if(rest[j] == 0){
                        out[j] = t;
                        flag[j]= 2;
                    }
                }
            }
            for(int j=0;j<N;++j)
                cout<<rest[j]<<" "; 
            cout<<endl;
            continue;
        }
        if( Ti[i] == t && !flag1 && (Ui[i] - rest[i-1]  >= S || rest[i-1] ==0) ){     //新放入 
            flag[i] = 1;
            for(int j=0 ; flag[j] != 0 ; ++j){
                if(flag[j]==1){
                    rest[j]--;
                    if(rest[j] == 0){
                        out[j] = t;
                        flag[j]= 2;
                    }
                }
            }
            flag1 = false;
            ++i;//处理下一架飞机
            time = -1;
            for(int j=0;j<N;++j)
                cout<<rest[j]<<" "; 
            cout<<t<<":新放入"<<endl; 
        }else if( Ti[i] == t && !flag1 && Ui[i] - rest[i-1] < S){ //新复飞 
            for(int j=0 ; flag[j] != 0 ; ++j){
                if(flag[j]==1){
                    rest[j]--;
                    if(rest[j] == 0){
                        out[j] = t;
                        flag[j]= 2;
                    }
                }
            }
            time = Gi[i]-1;flag1 = true;
            for(int j=0;j<N;++j)
                cout<<rest[j]<<" "; 
            cout<<t<<":新复飞"<<endl;
        }else if( time == 0 && (Ui[i] - rest[i-1]  >= S || rest[i-1] ==0)){ //旧放入 
            if(Ti[i+1] == t){
                cout<<"CHANGE BOYFRIEND"<<endl;
                flag2 = false;
                break;
            }
            flag[i] = 1;
            for(int j=0 ; flag[j] != 0 ; ++j){
                if(flag[j]==1){
                    rest[j]--;
                    if(rest[j] == 0){
                        out[j] = t;
                        flag[j]= 2;
                    }
                }
            }
            flag1 = false;
            ++i;//处理下一架飞机
            time = -1;
            for(int j=0;j<N;++j)
                cout<<rest[j]<<" "; 
            cout<<t<<":旧放入"<<endl;
        }else if( time == 0&& Ui[i] - rest[i-1] < S){ //旧复飞
            if(Ti[i+1] == t){
                cout<<"CHANGE BOYFRIEND"<<endl;
                flag2 = false;
                break;
            }
            for(int j=0 ; flag[j] != 0 ; ++j){
                if(flag[j]==1){
                    rest[j]--;
                    if(rest[j] == 0){
                        out[j] = t;
                        flag[j]= 2;
                    }
                }
            }
            time = Gi[i]-1;flag1 = true;
            for(int j=0;j<N;++j)
                cout<<rest[j]<<" "; 
            cout<<t<<":旧复飞"<<endl;
        }
        else if(flag1 && Ti[i+1] == t){                         //相撞 
                cout<<"CHANGE BOYFRIEND"<<endl;
                flag2 = false;
                break;
        }else{                         //没有飞机
             for(int j=0 ; flag[j] != 0 ; ++j){
                if(flag[j]==1){
                    rest[j]--;
                    if(rest[j] == 0){
                        out[j] = t;
                        flag[j]= 2;
                    }
                }
            }
            if(flag1)
                time--;
            for(int j=0;j<N;++j)
                cout<<rest[j]<<" "; 
            cout<<t<<":meifeiji"<<endl;
        }
        
    }
    if( (i!=N && flag2) || ( out[N-1] == 0 && flag2 ) ){
        cout<<"GO DATING"<<endl;
    }else if(flag2){
        for(int j=0;j<N;++j){
            cout<<out[j]+1<<endl;    
        }    
    }

结果还是不完全正确 -   。 -

几个问题:

1.飞机在降落区飞行时间 Ui 可能短于最短安全时间 S , 故改为(Ui[i] - rest[i-1]  >= S || rest[i-1] ==0)

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 乱打一组数据发现的

猜你喜欢

转载自blog.csdn.net/qq_40128883/article/details/88172858