Lanqiao

题目大致意思是给定 (n) 架飞机的最早降落时间 (t),盘旋时间 (d) 以及降落所需时间 (l),每架飞机从开始降落到降落结束过程中,其它飞机都不能降落,通俗得说就是这段时间里空中只有这一架飞机正在降落。求是否存在一种排列方案,使得所有飞机都可以降落到地面。

这道题本质上就是一个求不相交区间的问题,我一开始想到的是纯贪心,考试的时候,我通过直觉判断用最晚降落时间(t + d)进行升序排序,这样的容错率感觉会更高,样例应该是过了的。

但纯贪心的思路是错误的,由于这道题的数据比较小,最多只有10,所以应当递归实现全排列枚举,然后判断是否存在一种排列能够使得所有飞机降落成功即可。

对于每一层递归,只需要知道上一层的降落结束时刻 (last),由于每架飞机有一个最早降落时间 (t),所以当前一层递归的最早降落结束时刻应取 (max(last, t) + l),(l) 为降落所需时间。为了使得容错率更高,当最晚降落开始时间 (t + d) 大于等于 上一层的降落结束时刻,就可以将这架飞机作为下一个降落的飞机。

个人战况
我自己只想到贪心,估计只能过一半甚至都不到的样例。

#include<iostream>
#include<cstring>
using namespace std;

const int N = 12;
int n;
struct node{
    int t, d, l;  //t为此飞机的最早降落时间 d为盘旋时间 l为降落所需时间
}p[N];
bool st[N];

//DFS求全排列模型
bool dfs(int u, int last){
    if(u == n) return true;

    for(int i = 0; i < n; i ++ ){
        int t = p[i].t, d = p[i].d, l = p[i].l;
        if(st[i]) continue;
        if(t + d >= last){  //最晚降落时间t+d大于等于上一层的降落结束时刻
            st[i] = true;
            if(dfs(u + 1, max(last, t) + l)) return true; //当前层的最早降落结束时刻为max(last,t)+l
            st[i] = false;
        }
    }

    return false;
}

int main(){
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);

    int T; cin >> T;
    while(T -- ){
        cin >> n;
        for(int i = 0; i < n; i ++ ){
            int t, d, l; cin >> t >> d >> l;
            p[i] = {t, d, l};
        }

        memset(st, 0, sizeof(st));
        cout << (dfs(0, 0) ? "YES" : "NO") << endl;
    }

    return 0;
}
posted @ 2026-04-10 19:36  EcSilvia  阅读(3)  评论(0)    收藏  举报