题面
qwqkawaii is registering for () courses. In the registration system, he can submit a course wish for each course, which indicates his priority for taking that course.
Course wishes are divided into () priority levels, where level is the highest priority and level is the lowest.
The first wish levels have capacity limits: for each , at most courses can be assigned wish level . Note that wish level has no capacity limit.
Initially, the -th course has wish level , and it is guaranteed that this initial assignment satisfies all capacity limits. Now qwqkawaii wants to adjust all his courses to wish level . To achieve this, he can apply the following operation at most times:
- Select a course (), then increase by .
Note that:
- A course at level cannot be selected;
- After every single operation, all capacity limits must still be satisfied.
Your task is to construct a valid adjustment sequence with at most operations, or report that it is impossible.
Input
Each test contains multiple test cases. The first line contains the number of test cases (). The description of the test cases follows.
The first line of each test case contains two integers and (, ) — the number of courses and the number of priority levels (excluding the lowest priority level).
The second line contains integers () — the capacity limits of the first wish levels.
The third line contains integers () — the initial wish levels of the courses.
It is guaranteed that the initial assignment satisfies all capacity limits.
Output
For each test case, if it is impossible to reach the target state, print a single integer .
Otherwise, print the number of operations () on the first line of output.
Then print one line with integers (), denoting that in the -th operation, you increase the wish level of course by .
思路
题目要求构造一种操作顺序,把所有课程从当前等级逐步提升到 ,并且每一步后都不能违反容量限制
考虑贪心:每次都从当前“最高的非空等级”中取一门课上移
设当前最高非空等级为 (),把一门课从 移到 :
- 层人数减少,一定不会超容量
- 由于 已经是当前最高层,所以 都为空,特别是 层原本为
- 移动后 层最多变成 ,而题目给出 ,因此也合法
- 若 ,则进入 (无容量限制),同样合法
因此这个过程一定可以持续进行,直到 全部为空,此时所有课程都在
总操作数是固定的:
由约束 ,有 ,满足题目要求
实现时可用 levels[1..k+1] 存每个等级的课程编号,每轮从 向 找最高非空层并执行一次移动,记录课程编号到答案即可。复杂度为
代码
#include <bits/stdc++.h>
using namespace std;
int main() { ios::sync_with_stdio(false); cin.tie(nullptr);
int t; cin >> t; while (t--) { int n, k; cin >> n >> k;
vector<int> a(k + 1), b(n + 1); for (int i = 1; i <= k; i++) cin >> a[i]; for (int i = 1; i <= n; i++) cin >> b[i];
vector<vector<int>> levels(k + 2); vector<int> cnt(k + 2, 0);
for (int i = 1; i <= n; i++) { levels[b[i]].push_back(i); if (b[i] <= k) cnt[b[i]]++; }
vector<int> ans; ans.reserve(1000);
bool fail = false;
while (true) { int x = 0; for (int lv = k; lv >= 1; lv--) { if (!levels[lv].empty()) { x = lv; break; } }
if (x == 0) break;
if (x < k && cnt[x + 1] + 1 > a[x + 1]) { fail = true; break; }
int id = levels[x].back(); levels[x].pop_back();
ans.push_back(id);
cnt[x]--; if (x + 1 <= k) cnt[x + 1]++;
levels[x + 1].push_back(id);
if ((int)ans.size() > 1000) { fail = true; break; } }
if (fail) { cout << -1 << '\n'; continue; }
cout << ans.size() << '\n'; for (int i = 0; i < (int)ans.size(); i++) { if (i) cout << ' '; cout << ans[i]; } cout << '\n'; }
return 0;}