C++ 蓝桥杯2023真题:飞机降落

文章讨论了如何在只有一个跑道的机场安排N架飞机安全降落的问题,通过DFS算法检查飞机的到达时间、盘旋时间和降落时间,判断是否存在冲突。
摘要由CSDN通过智能技术生成

题目描述

       N 架飞机准备降落到某个只有一条跑道的机场。其中第 i 架飞机在 Ti 时刻到达机场上空,到达时它的剩余油料还可以继续盘旋 Di 个单位时间,即它最早可以于 Ti 时刻开始降落,最晚可以于 Ti + Di 时刻开始降落。降落过程需要 Li个单位时间。一架飞机降落完毕时,另一架飞机可以立即在同一时刻开始降落,但是不能在前一架飞机完成降落前开始降落。请你判断 N 架飞机是否可以全部安全降落。

输入格式

       输入包含多组数据。

       第一行包含一个整数 T,代表测试数据的组数。

       对于每组数据,第一行包含一个整数 N。

       以下 N 行,每行包含三个整数:Ti,Di 和 Li。

输出格式

       对于每组数据,输出 YES 或者 NO,代表是否可以全部安全降落。

样例输入

       2
       3
       0 100 10
       10 10 10
       0 2 20
       3
       0 10 20
       10 10 20
       20 10 20

样例输出

       YES
       NO

提示

       对于第一组数据,可以安排第 3 架飞机于 0 时刻开始降落,20 时刻完成降落。安排第 2 架飞机于 20 时刻开始降落,30 时刻完成降落。安排第 1 架飞机于 30 时刻开始降落,40 时刻完成降落。对于第二组数据,无论如何安排,都会有飞机不能及时降落。

       对于 30% 的数据,N ≤ 2。

       对于 100% 的数据,1 ≤ T ≤ 10,1 ≤ N ≤ 10,0 ≤ Ti , Di , Li ≤ 105。

题解

       根据提示,飞机数最大为10架。数据大小为几十时,DFS暴力枚举往往就是正确答案。即将一组的飞机进行全排列,只要一种组合可以全部安全降落就输出 “YES”。

       要明确两个点:

       1,不能安全降落的条件:如果第 2 架飞机的到达时间和盘旋时间之和小于第 1 架飞机的降落时间,第 1 架飞机就不能安全降落。推广可得,第 n 架飞机的到达时间和盘旋时间之和小于0时刻~第 n-1 架飞机降落时刻的时间,第 n 架飞机就不能安全降落。

       2,第 n 架飞机降落时刻如何计算:取第 n-1 架飞机降落时刻和第 n 架飞机到达时间中的最大值加上第 n 架飞机的降落时间。

代码

#include<iostream>
using namespace std;
#define Nmax 11  //最大飞机数 

struct plane{
	int T,D,L;  //每架飞机的三个参数 
}p[Nmax];  //定义飞机组 

bool st[Nmax];  //判断当前飞机是否已经降落 

bool DFS(int u,int time,int N) {  //u:已降落飞机数  time:当前时间,即上一架飞机降落时刻  N:本组飞机数 
	if(u>=N)     //全部安全降落 
		return true;
	for(int i=0;i<N;i++){  //判断下一个降落的飞机 
		if(!st[i]){  //st[i]=false 未降落 
			if(p[i].T+p[i].D<time){  //该飞机到达时间+盘旋时间 < 小于上一架飞机降落时刻 
				return false;  //不能安全降落 
			} 
			st[i]=true;  //该飞机安全降落,标记为true 
			int t=(time>p[i].T?time:p[i].T)+p[i].L;  //当前时间为 max(上一架飞机降落时刻,该飞机到达时间)+ 该飞机降落时间 
		    if(DFS(u+1,t,N))  //递归调用 DFS
				return true;  
			st[i]=false;   //回溯之前的状态 
		}
	}
	return false;
}

int main()
{
    int T;
    cin>>T;
    while(T--){
    	int N;
    	cin>>N;
    	
    	for(int i=0;i<N;i++){
    		cin>>p[i].T>>p[i].D>>p[i].L;
		}
		if(DFS(0,0,N))
			cout<<"YES"<<endl;
		else
			cout<<"NO"<<endl;
		
		for(int i=0;i<N;i++)
			st[i]=false; 
	}
    return 0;
}

  • 9
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值