CF 730 A.Toda 2
A. Toda 2
题目大意
给定一个长度为的数组。每次操作可以选择2到5个数,是其减一,如果该数为0则不变。最终所有数相等。问这个相等的最大值是多少。注意操作数不得大于 。
解题思路
注意到就算每次选一个数是其减一,最后全部减到0所需要的操作数也刚好是。因此这个操作数上限无需考虑。
注意到每次选择4个数可以拆成两次选择两个数,选择5个数可以拆成一次选择两个数和一次选择三个数。因此这两种选法无需考虑,只需考虑选择2个数和3个数的。
一个直观的想法就是,令目标数为当前最小的数,然后每次选择最大的两个数,是其减一。直到剩下一个数不是val,看看它减到val的次数能不能插到之前的操作里(注意之前的操作该数不能减一),可以的话就可行,不行的话就令 减一,重复上述步骤。
由于最多次操作,用堆模拟这个过程即可。用 数组记录有多少个操作某个数减一。
神奇的代码
#include <bits/stdc++.h> using namespace std; typedef long long LL; int main(void) { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); int n; cin >> n; priority_queue<pair<int, int>> tt; int minn = 1e9 + 7; for(int i = 0; i < n; ++ i){ int x; cin >> x; minn = min(minn, x); tt.push({x, i}); } vector<pair<int, int>> ans; vector<int> down(n, 0); int leff = 0; int cc = 0; while(tt.top().first != minn){ auto t1 = tt.top(); tt.pop(); auto t2 = tt.top(); tt.pop(); if (t2.first == minn){ if ((int)ans.size() - down[t1.second] >= t1.first - minn){ leff = t1.second; cc = t1.first - minn; break; }else{ minn = max(minn - 1, 0); } } ans.push_back({t1.second, t2.second}); down[t1.second] ++; down[t2.second] ++; t1.first = max(t1.first - 1, 0); t2.first = max(t2.first - 1, 0); tt.push(t1); tt.push(t2); } cout << minn << '\n'; cout << ans.size() << '\n'; string s (n, '0'); for(auto i : ans){ s[i.first] = '1'; s[i.second] = '1'; if (i.first != leff && i.second != leff && cc) s[leff] = '1'; cout << s << '\n'; s[i.first] = '0'; s[i.second] = '0'; if (i.first != leff && i.second != leff && cc){ s[leff] = '0'; -- cc; } } return 0; }
本文作者:~Lanly~
本文链接:https://www.cnblogs.com/Lanly/p/16104164.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步