专栏文章
题解:P8838 [传智杯 #3 决赛] 面试
P8838题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @miof1xic
- 此快照首次捕获于
- 2025/12/02 18:09 3 个月前
- 此快照最后确认于
- 2025/12/02 18:09 3 个月前
一道搜索题。
思路分析
用 dfs 暴力枚举即可,由于 ,所以解法不会超时。
dfs 每一个指令,匹配每一个服务器,只要找到第一种解,就是字典序最小的,因为每一层遍历都是从小到大的。
1. 确定递归边界:
当 个指令都匹配完后,就找到了正解。
CPPif (x == k + 1) { // 指令都匹配完了
for (int i = 1; i <= n; i++) cout << ans[i] << " "; // 输出正解序列
exit(0); // 结束程序
}
2. 循环匹配服务器:
用
for 循环给当前指令匹配每一个服务器。只要当前服务器 能处理当前指令 ()并且当前服务器没有被其他指令匹配过,就可以匹配。
CPPfor (int i = 1; i <= n; i++) // 寻找合适的服务器
if (!vis[i] && a[i] >= b[x]) { // 满足匹配条件
vis[i] = true; // 标记为匹配过
ans[x] = i; // 记录答案
dfs(x + 1); // dfs 下一层
vis[i] = false; // 回溯
}
最后判无解。只要在 dfs 时没找到正解,就是无解,输出
-1。完整 AC 代码
CPP#include<iostream>
using namespace std;
int n, k;
int a[10], b[10];
int ans[10], vis[10];
void dfs(int x) {
if (x == k + 1) {
for (int i = 1; i <= n; i++) cout << ans[i] << " ";
exit(0);
}
for (int i = 1; i <= n; i++)
if (!vis[i] && a[i] >= b[x]) {
vis[i] = true;
ans[x] = i;
dfs(x + 1);
vis[i] = false;
}
}
int main() {
cin >> n >> k;
for (int i = 1; i <= n; i++) cin >> a[i];
for (int i = 1; i <= k; i++) cin >> b[i];
dfs(1); // 暴力枚举
cout << -1; // 无解
return 0;
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...