考试周,好久没刷题了
最近,kuangbin的题单暂时 松一松 。大概松半个月左右。
cf上分要抓紧了。
这题我没看出来,我是有思路的。
我们注意到,对于一个操作:- num1
如果他的前面有- nun2
若num2>num1
则在num2后面,num1应该放置。
num1是绝对不可以放在num2前面的。且- num1这个操作实行前一定要放置num1
根据这个信息我们想想到底应该怎么放置
就近放置 优先队列存储pos
遇到一个+就存上一个++pos
遇到一个- 就在顶部的pos处放置
我们想想,我在最大 的pos处放置,能够最大限度地避免自己被放在前面比我大num前
那问题来了,值会对后面的数无影响吗?
如果正好我后面的数小于我,那么很明显至今为止地所有pos都不能放,
一放就完蛋。
只能放我后面的-和我地-中间夹杂的+
还有所以我就算放在至今最靠后的pos上也是无关紧要的。
如果后面的比我大那就更没必要了就放在我前面还是放在我后面,完全没影响。
那如果,我的后驱比我大但是比我前面的小呢 ?
我们放在最后面的pos还是最有操作。
因为,如果上面的假设成立。那么我也一定比前面的小。
那么我放在最后面,自然而然也不会有什么问题。
说的很迷,构造题真难!!!!
#include<iostream> #include<vector> #include<functional> #include<queue> using namespace std; typedef pair<char, int> pci; const int max_n = 1e5 + 100; pci ops[max_n << 1]; int ans[max_n]; int main() { ios::sync_with_stdio(0); int n;cin >> n; for (int i = 1;i <= 2 * n;++i) { cin >> ops[i].first; if (ops[i].first == '-') cin >> ops[i].second; }priority_queue<int> que; int pos = 0; for (int i = 1;i <= 2 * n;++i) { if (ops[i].first == '+')que.push(++pos); else { if (que.empty()) { cout << "NO\n"; return 0; }int pp = que.top(); que.pop(); ans[pp] = ops[i].second; } }priority_queue<int,vector<int>,greater<int>> set;int ii = 1; for (int i = 1;i <= 2 * n;++i) { if (ops[i].first == '+') set.push(ans[ii++]); else { int num = set.top(); set.pop(); if (num != ops[i].second) { cout << "NO\n"; return 0; } } }cout << "YES\n"; for (int i = 1;i <= n;++i) cout << ans[i] << " "; cout << endl; }