飞机降落(DFS)
蓝桥杯2023年第十四届省赛真题-飞机降落 - C语言网 (dotcpp.com)
一开始我是真的没想到用DFS做,我还在想用什么策略排序呢。需要再刷!!!
双马尾的意思其实是刷了两次...
一刷:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
//这道题是真的牛逼。他没有策略,而是用DFS遍历所有情况,然后判断每一种情况可不可行,
//如果所有的都不可行,那就说明总的不可行
//真的无脑我去struct Plane
{int t; //到达时间int d; //盘旋时间int l; //降落时间
};int n, cnt;vector<Plane>flys;
vector<int>visit(11); //记录bool DFS(int num,int last) //已经降落的数量 最后降落时间
{if (num==cnt)return true;for (int i = 0; i < cnt; i++){if (visit[i] == 0 && last <= flys[i].t + flys[i].d){visit[i] = 1;//现在的last应该是最近能降落的时间+降落持续时间if (DFS(num + 1, max(last, flys[i].t) + flys[i].l)) //如果之后的所有情况都可以实现return true;visit[i] = 0;}}return false;
}int main()
{cin >> n;int t, d, l;for(int i=0;i<n;i++){cin >> cnt;flys.clear();for (int i = 0; i < 11; i++)visit[i] = 0;for(int j=0;j<cnt;j++) //输入数据{cin >> t >> d >> l;flys.push_back({ t,d,l });}if (DFS(0,0)) cout << "YES" << endl;else cout << "NO" << endl;}return 0;
}
二刷:
虽然同样是用DFS,但是这次策略有所不同:一旦得到一个解,那就咔咔全部返回,直接输出,比之前的快了不少。
//飞机降落
#include <iostream>
#include <vector>
#include <cstring>
using namespace std;struct Time
{int t,d,l; //到达时间,最大盘旋时间,降落时间 };int n,m;
Time plane[11];
int book[11];bool dfs(int last,int cnt) //last 上一趟飞机结束时间 cnt当前已经遍历过的飞机数
{if(cnt==m) return true;for(int i=0;i<m;i++) //遍历所有的飞机,作为下一趟 {Time nex=plane[i];if(last>nex.t+nex.d || book[i]==1) continue; //如果时间不合适或者已经标记过,不行 book[i]=1;if(dfs(max(last,nex.t)+nex.l,cnt+1)) return true;book[i]=0; //回溯 } return false; //所有方案都不行
}int main()
{cin>>n;while(n--){cin>>m;memset(book,0,sizeof(book));memset(plane,0,sizeof(plane));for(int i=0;i<m;i++)cin>>plane[i].t>>plane[i].d>>plane[i].l;if(dfs(0,0)) cout<<"YES"<<endl;else cout<<"NO"<<endl;}return 0;}