原题链接:[蓝桥杯 2023 省 B] 飞机降落 - 洛谷
目录
1. 题目描述
2. 思路分析
3. 代码实现
1. 题目描述
2. 思路分析
dfs全排列的变形题。
因为最后问飞机是否降落,并且一架飞机降落完毕时另一架飞机才能降落。所以我们设置dfs的两个变量cnt为安全降落的飞机数量cnt和上一架飞机降落的时间sum。
设置一个vis[ ]数组表示当前飞机有没有被搜过,一个变量f表示所有飞机是否能安全降落,如果能f最后值为1,否则为0。
dfs入口就写dfs(0,0),进行搜索即可。
当前飞机如果能安全降落,那么它最晚的降落时间(t[i]+d[i],因为能盘旋在空中)必须大于等于上一架飞机降落的时间sum。也就是能往下搜的条件是首先飞机没有被搜过(!vis[i]),同时t[i]+d[i]>=sum (该飞机最晚降落时间大于等于上一架飞机降落时间)。
要搜下一架飞机时,这时候要dfs(cnt+1,max(t[i],sum)+l[i]),之所以要取max,就是如果当前飞机的降落时间t[i]比sum小,就从上一架飞机降落的时间sum开始降落,否则就以t[i]时间开始降落。
注意要回溯
3. 代码实现
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
const int N=20;
int n,t[N],d[N],l[N],f;
bool vis[N];
void dfs(int cnt,int sum){
if(cnt==n){
f=1; return;
}
for(int i=1;i<=n;i++){
if(!vis[i]&&t[i]+d[i]>=sum){
vis[i]=true;
dfs(cnt+1,max(t[i],sum)+l[i]);
vis[i]=false;
}
}
}
signed main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int _; cin>>_;
while(_--){
cin>>n;
for(int i=1;i<=n;i++) vis[i]=0;
f=0;
for(int i=1;i<=n;i++){
cin>>t[i]>>d[i]>>l[i];
}
dfs(0,0);
if(f) cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
return 0;
}