AtCoder Regular Contest 153
A - AABCDDEFE (arc153 a)
题目大意
给定一个仅包含数字的字符串,称它为好的,当且仅当其包含个数字,且
给定,问字符串第 小的好串。
解题思路
自由位置其实只有六个,因此可以预处理这个,或者将每位拆解赋值到对应位置即可。
神奇的代码
#include <bits/stdc++.h> using namespace std; using LL = long long; int main(void) { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); LL n; cin >> n; -- n; vector<int> qwq; while(n){ qwq.push_back(n % 10); n /= 10; } string s(9, '0'); s[0] = '1'; s[1] = '1'; if (qwq.size() > 0) s[7] += qwq[0]; if (qwq.size() > 1){ s[6] += qwq[1]; s[8] += qwq[1]; } if (qwq.size() > 2){ s[4] += qwq[2]; s[5] += qwq[2]; } if (qwq.size() > 3){ s[3] += qwq[3]; } if (qwq.size() > 4){ s[2] += qwq[4]; } if (qwq.size() > 5){ s[1] += qwq[5]; s[0] += qwq[5]; } cout << s << '\n'; return 0; }
B - Grid Rotations (arc153 b)
题目大意
给定一个的网格,进行 次操作,每次操作包含两个数,将网格分成四部分,其中左上部分的右下角为 ,然后对四个部分分别旋转180度。
问 次操作的网格图样子。
解题思路
考虑一维的情况,比如 1 2 3 4 5 6
,我们将头尾视为相连,即的左边是 。假定选择一个位置进行翻转,比如选择 4
,就变成4 3 2 1 6 5
,观察1
左右两边的数,始终都是 2,6
,只是左右方向变了,其他数亦是如此。
因此将头尾连成一个环形关系,每次操作都不会改变该环形关系,只是左右对调了。
拓展到二维的话,就是将上下相连,左右相连,形成一个球形关系,每次操作同样不会改变这个球形关系,只是上下交换,左右交换了。
因此我们只要处理出一个位置经过次操作后的位置,然后再根据原来的球形关系还原出答案即可。
神奇的代码
#include <bits/stdc++.h> using namespace std; using LL = long long; int main(void) { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); int h, w; cin >> h >> w; vector<string> s(h); for(auto &i : s){ cin >> i; } int sx = 0, sy = 0; auto change = [&](int x, int y){ if (sx <= x){ int rh = x + 1; sx = rh - sx - 1; }else { int rh = h - x - 1; sx -= x + 1; sx = rh - sx - 1; sx += x + 1; } if (sy <= y){ int rw = y + 1; sy = rw - sy - 1; }else { int rw = w - y - 1; sy -= y + 1; sy = rw - sy - 1; sy += y + 1; } }; int q; cin >> q; int dir = -2 * (q & 1) + 1; while(q--){ int x, y; cin >> x >> y; -- x, --y; change(x, y); } vector<vector<char>> ans(h, vector<char>(w)); for(int i = 0; i < h; ++ i){ for(int j = 0; j < w; ++ j){ ans[sx][sy] = s[i][j]; sy = (sy + w + dir) % w; } sx = (sx + h + dir) % h; } for(auto &i : ans){ for(auto &j : i) cout << j; cout << '\n'; } return 0; }
C - ± Increasing Sequence (arc153 c)
题目大意
给定一个长度为,仅包含的数组 。要求构造一个长度一样为的数组,满足
- 数组严格递增
不存在则告知该事实。
解题思路
想的很朴素,就是先填充为 。然后计算下 的值。
- 如果 就皆大欢喜。
- 如果 ,就找一个数组前缀和为的下标 ,则 ,的值就会 。因此令 ,这样就变成 了,同时还保证了递增条件。因为,因此不会 超出范围。
- 如果 ,就找一个数组前缀和为的下标 ,则 ,的值就会 。因此令 ,这样就变成 了。同时还保证了递增条件。因为,因此不会 超出范围。
如果找不到对应的下标,就无解了(应该指这类初始情况的填法无解,因为初始严格递增的填法限制了改动范围只能是个前缀或后缀,但不清楚能否对应原问题的无解)(原本还想着倒着找个后缀和+1的,但过了)被评论区数据hack了,加上了这个判断。
因为只有 和 ,所以其前缀和相邻项最多相差 ,第一个大于 的必然是 ,反之也是 。
神奇的代码
#include <bits/stdc++.h> using namespace std; using LL = long long; int main(void) { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); int n; cin >> n; vector<LL> a(n); vector<LL> sufa(n); vector<LL> prea(n); for(auto &i : a) cin >> i; vector<LL> ans(n); LL st = 1; iota(ans.begin(), ans.end(), st); LL sum = 0; for(int i = 0; i < n; ++ i) sum += ans[i] * a[i]; partial_sum(a.begin(), a.end(), prea.begin()); partial_sum(a.rbegin(), a.rend(), sufa.rbegin()); auto solve = [&](){ if (sum == 0) return true; if (sum < 0){ for(auto &i : prea) i *= -1; for(auto &i : sufa) i *= -1; sum *= -1; } int pos = 0; for(; pos < n; ++ pos) if (prea[pos] > 0) break; if (pos == n){ for(pos = n - 1; pos >= 0; -- pos) if (sufa[pos] < 0) break; if (pos == -1) return false; for(int i = n - 1; i >= pos; -- i) ans[i] += sum; return true; }else{ for(int i = 0; i <= pos; ++ i){ ans[i] -= sum; } return true; } }; if (solve()){ cout << "Yes" << '\n'; for(auto &i : ans) cout << i << ' '; cout << '\n'; }else{ cout << "No" << '\n'; } return 0; }
D - Sum of Sum of Digits (arc153 d)
题目大意
给定一个长度为的数组,要求找到一个 ,使得 最小,其中 表示 在十进制下各个数字的和,比如
输出该最小值。
解题思路
<++>
神奇的代码
E - Deque Minimization (arc153 e)
题目大意
<++>
解题思路
<++>
神奇的代码
F - Tri-Colored Paths (arc153 f)
题目大意
<++>
解题思路
<++>
神奇的代码
本文作者:~Lanly~
本文链接:https://www.cnblogs.com/Lanly/p/17053734.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
2020-01-15 Educational Codeforces Round 80 (Rated for Div. 2)