c++ · 洛谷P9241飞机降落 · 复盘
·
P9241 [蓝桥杯 2023 省 B] 飞机降落 - 洛谷
一:题目分析:
已知一组飞机的到达时间 t,可盘旋时间 d,降落所需时间 l,判断是否存在一组降落顺序,使得所有飞机都顺利降落,存在输出YES,否则输出NO;
二:思路:
数据结构部分:
1.设置结构体plane,存储每架飞机的三个信息;
2.设置两个数组a[N],b[N],前者按输入顺序存储要判断的这一组飞机信息,后者存储当前尝试的降落顺序;
3.设置bool数组vis[N],飞机降落过则true,反之是false;
4.设置bool变量f,用来判断是否已经找到一种方案,如果f=false,则说明还没有找到可执行的顺序;
DFS函数部分:
1.参数x:表示当前正在尝试安排第x架飞机;
2.该函数的作用:
(1):能修改全局变量f,如果f=true,则找到了可执行的方案;
(2):改变全局变量b,让其存储当前正在尝试的降落顺序;
(3):修改全局变量vis数组,判断哪些飞机是降落过的;
3.结束条件:f==true,直接返回,每次安排完顺序之后,检查当前顺序是否可行;
4.递归:
(1):遍历这一组所有飞机,选择为未降落的飞机,加入b数组中,并且标记;
(2):递归调用dfs(x+1),尝试安排下一架函数,如果不符合条件,则回溯撤回,返回上一步方案,尝试其他的解;
主函数部分:
1.运用memset函数,把b数组的所有元素初始化为0,确保每次开始一组数据的测试的时候,b数组都是干净的;
附超多注释代码:
#include <bits/stdc++.h>
#define ll long long
using namespace std;
int n, t;
const int N = 11;
bool vis[N], f; // vis数组判断当前飞机是否已经降落过,true表示已经降落过,false表示还没有降落过
// f用来判断是否已经找到一种方案
// 当f为false的时候,表示还没有找到可行的降落顺序
struct plane
{
int t, d, l;
} a[N], b[N];
// 这个写法等同于:
// plane a[N], b[N];
// a数组按顺序存储输入的飞机信息,是原始数据,不会被修改
// b数组是当前正在尝试的降落顺序,会随着dfs函数的递归调用而改变
// 这个dfs的作用:
// 1.能修改全局变量f,当f为true的时候,表示已经找到一种方案
// 2.能修改全局变量b,b数组存储当前正在尝试的降落顺序
// 3.能修改全局变量vis,vis数组判断哪些飞机是降落过的
void dfs(int x) // 递归函数,用于尝试所有可能的飞机降落顺序
// d表示当前正在尝试安排第d架飞机
{
if (f) // 如果已经找到解,直接返回
return;
if (x > n) // 这时候安排完了所有的飞机,也就是生成了一种方案
// 开始判断这个方案是否可行
{
int ls = b[1].t + b[1].l; // ls表示第一家飞机降落完毕的时间
// 因为可以直接降落,不需要盘旋,所以不用加上b[1].d
// ls在下面循环中的作用是记录当前飞机降落完毕的时间
int fl = 1; // fl是一个标志位,用于表示当前顺序是否可行,
// 0:不可行,1:可行
for (int i = 2; i <= n; i++)
{ // 从第二架飞机开始判断
if (ls > b[i].t + b[i].d)
{ // b[i].t + b[i].d表示当前飞机的最晚降落时间
// 如果小于上一架飞机的降落完毕时间,则无法降落
fl = 0;
break;
}
// 如果前一架飞机的降落完成时间>当前飞机最早到达时间
// 也就是说明当前飞机需要盘旋一段时间再降落
else if (ls > b[i].t)
ls += b[i].l;
// 则前一架飞机降落完,现在飞机降落
// 现在的飞机降落需要l,则ls += b[i].l;
else
// 这种情况是ls <= b[i].t
// 也就是当前飞机可以直接降落,不需要盘旋
ls = b[i].l + b[i].t;
}
if (fl == 1)
{
f = true; // 如果当前方案可行,则将f置为true,表示已经找到解
}
}
for (int i = 1; i <= n; i++) // 遍历所有的飞机
if (!vis[i]) // 如果当前飞机还没有降落过
{
vis[i] = true; // 标记当前飞机已经降落
b[x] = a[i]; // 将当前飞机的信息存入b数组,构造当前尝试的降落顺序
dfs(x + 1); // 递归调用dfs函数,尝试下一架飞机
// 如果当前方案不可行,会退回上一步,尝试其他方案
vis[i] = false;
}
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin >> t; // t组数据
while (t--)
{
cin >> n; // n架飞机
f = false;
memset(b, 0, sizeof b);
// 这个函数的意思是:将b数组中的所有元素都置为0;sizeof(b)表示b数组所占的字节数;
for (int i = 1; i <= n; i++)
cin >> a[i].t >> a[i].d >> a[i].l;
dfs(1); // 从第一架飞机开始尝试降落
if (f)
cout << "YES\n";
else
cout << "NO\n";
}
return 0;
}
更多推荐



所有评论(0)