题目3151:蓝桥杯2023年第十四届省赛真题-飞机降落 C++

花了3个小时完成,对我来说就是纯纯数学思路。

思路:每架飞机有三个变量,可以衍生为四个,T1、T2、L1、L,分别代表飞机最初起飞时间、飞机最晚起飞时间、飞机从当前起飞时间(如果最早起飞时间大于当前起飞时间,按最早起飞时间算)到降落后的时间,飞机所需降落时间。其中主要针对T2和L1作比较。T1和L是为了更新L1的。设chu=0,即初始时间为0。用数组J保存每架飞机的数据。对所有没降落的飞机的T2求最小min1和下标x,L1求最小min2和下标y(用L是否为0判断是否降落)。分别得到T2和L1的最小值min1、min2。如果chu>min1说明到达chu时间,对应的x飞机的最晚起飞时间已经过了,所以直接判断no跳出循环(注意把结果存到数组A中)。如果min1<min2(说明飞机x最晚起飞时间要小于飞机y的到达时间,考虑的都是最值,所以必须让x先降落),则对x飞机降落(标记L=0)。反之,则对y先降落。再通过循环找新的未降落的min1和min2。最终如果到了所有飞机全部降落都没有跳出,则标记yes(存结果到A中)。

(1)输入N(有N组数据,需要验算是否可以)(用bool数组A存储结果)

(2)把总体分为N组,一组一组思考

第i组:

输入T,有T架飞机,定义一个类F来表示每架飞机

class F {
public:int T1, T2,L,L1;//T1~T2为可起飞时间段,从当前时间L1为起飞到降落时间
	  F():T1(0),T2(0),L(0),L1(0){}//如果L为0表示已经降落
	  void getF(int a, int b, int c) { T1 = a; T2 = a + b; L = c; L1 = L + a; }
	  void LL(int chu) { L1= chu+L; }
};

T1~T2表示该飞机可起飞时间段(T1为最早起始时间,T2=T1+Di即起始时间加可转时间,L降落所需时间,L1=L+T1即从起始时间到降落后的时间)

用函数getF对每个变量赋值。

由于随着其它飞机起飞,L1会因为起始起飞时间变化而变化,即当chu(出发时间)>T1,L1要改变。故定义了一个类函数LL。

按照思路写代码:

#include<iostream>
#include<vector>
using namespace std;
class F {
public:int T1, T2,L,L1;//T1~T2为可起飞时间段,从当前时间L1为起飞到降落时间
	  F():T1(0),T2(0),L(0),L1(0){}//如果L为0表示已经降落
	  void getF(int a, int b, int c) { T1 = a; T2 = a + b; L = c; L1 = L + a; }
	  void LL(int chu) { L1= chu+L; }
};
vector<bool> A;
void ch(bool a) {
	if (a) cout << "YES\n";
	else cout << "NO\n";
}
int main() {
	int N, T;
	cin >> N;
	for (int i = 1; i <= N; i++)
	{
		int a, b, c,min1,min2,x=0,y=0,chu=0;
		cin >> T;
		vector<F> J(T);
		for (int j = 0; j <T; j++)
		{
			cin >> a >> b >> c;
			J[j].getF(a, b, c);
			if (j == 0) { min1 = J[j].T2; min2 = J[j].L1; }
			else {
				if (min1 > J[j].T2)
				{min1 = J[j].T2;	x = j;}
				if (min2 >J[j].L1)
				{min2 = J[j].L1;	y = j;}
			}
		}
		for (int j = 0; j < T; j++) {
			if (chu > min1) { A.push_back(0); break; }
			if (min1 < min2) { chu = J[x].L1; J[x].L = 0; }//min1的先飞
			else { chu = J[y].L1; J[y].L = 0; }
			min1 = 10000000; min2 = 10000000;
			for (int k = 0; k < T; k++) {
				if (J[k].L == 0) continue;
				if(J[k].T1<chu)
				    J[k].LL(chu);
				if (min1 > J[k].T2)
				{
					min1 = J[k].T2;	x = k;
				}
				if (min2 > J[k].L1)
				{
					min2 = J[k].L1;	y = k;
				}
			}
			if (j == T - 1 || min2 == 10000000 || min1 == 10000000)
			{
				A.push_back(1);
				break;
			}
		}
	}
	for (int i = 0; i < A.size(); i++)
		ch(A[i]);
	return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值