侧边栏壁纸
博主头像
GabrielxD

列車は必ず次の駅へ。では舞台は?私たちは?

  • 累计撰写 674 篇文章
  • 累计创建 128 个标签
  • 累计收到 20 条评论

目 录CONTENT

文章目录

【DFS】飞机降落【十四届蓝桥杯省赛CB】

GabrielxD
2023-04-13 / 0 评论 / 0 点赞 / 127 阅读 / 1,005 字
温馨提示:
本文最后更新于 2023-04-13,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

题目

4957. 飞机降落 - AcWing题库

蓝桥杯2023年第十四届省赛真题-飞机降落 - C语言网


NN 架飞机准备降落到某个只有一条跑道的机场。

其中第 ii 架飞机在 TiT_i 时刻到达机场上空,到达时它的剩余油料还可以继续盘旋 DiD_i 个单位时间,即它最早可以于 TiT_i 时刻开始降落,最晚可以于 Ti+DiT_i + D_i 时刻开始降落。

降落过程需要 LiL_i 个单位时间。

一架飞机降落完毕时,另一架飞机可以立即在同一时刻开始降落,但是不能在前一架飞机完成降落前开始降落。

请你判断 NN 架飞机是否可以全部安全降落。

输入格式

输入包含多组数据。

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

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

以下 NN 行,每行包含三个整数: TiT_iDiD_iLiL_i

输出格式

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

数据范围

对于 30%30\% 的数据, N2N ≤ 2
对于 100%100\% 的数据, 1T101 ≤ T ≤ 101N101 ≤ N ≤ 100Ti,Di,Li1050 ≤ T_i, D_i, L_i ≤ 10^5

输入样例:

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

输出样例:

YES
NO

样例解释

对于第一组数据,可以安排第 33 架飞机于 00 时刻开始降落, 2020 时刻完成降落。安排第 22 架飞机于 2020 时刻开始降落, 3030 时刻完成降落。安排第 11 架飞机于 3030 时刻开始降落, 4040 时刻完成降落。

对于第二组数据,无论如何安排,都会有飞机不能及时降落。

解题

方法一:DFS

思路

数据范围比较小,显然可以直接上暴搜(所有飞机的全排列)。

dfs(u,tm)dfs(u, tm)uu 表示当前有多少架飞机已降落, tmtm 表示已经花费的时间):

  • 出口:当 u=nu = n 时,说明所有飞机都安全降落,把 suc 置为 true ,退出程序。
  • 枚举第 0n10 \dots n - 1 架飞机:
    • 如果当前飞机( ii )还没有降落( done[i] == false ):
      • 如果发现当前时间已经超过了该飞机的最晚起飞时刻( t[i] + d[i] < tm ),说明这个飞机并不可能安全降落,直接退出递归(可行性剪枝);
      • 否则尝试降落该飞机( done[i] = true ),递归下一架飞机( dfs(u+1,max(Ti,tm)+Li)dfs(u + 1, \max(T_i, tm) + L_i) )(这里需要取 TiT_itmtm 的最大值是因为不能让当前飞机的起飞时间早于其最早起飞时间);
      • 回溯( done[i] = false )。

代码

#include <iostream>
#include <cstring>

using namespace std;

const int N = 20;
int m, n;
int t[N], d[N], l[N];
bool suc = false;
bool done[N];

void dfs(int u, int tm) {
    if (u == n) {
        suc = true;
        return;
    }
    for (int i = 0; i < n; ++i) {
        if (done[i]) continue;
        if (t[i] + d[i] < tm) return;
        done[i] = true;
        dfs(u + 1, max(t[i], tm) + l[i]);
        done[i] = false;
    }
}

int main() {
    int m;
    scanf("%d", &m);
    while (m--) {
        scanf("%d", &n);
        for (int i = 0; i < n; ++i) scanf("%d%d%d", &t[i], &d[i], &l[i]);
        suc = false;
        memset(done, false, sizeof(done));
        dfs(0, 0);
        puts(suc ? "YES" : "NO");
    }
    return 0;
}
0

评论区