AtCoder Beginner Contest 233题解
目前补到E题
A - 10yen Stamp
题目描述:给你两个正整数\(x\) 和\(y\),求最小的非负整数\(n\)使得不等式\(x + 10 * n \geq y\)成立。
思路:根据题意模拟即可
时间复杂度:\(O(1)\)
参考代码:
void solve() {
int x(0), y(0) , res(0);
cin >> x >> y;
if (x < y) res = (y - x + 9) / 10;
cout << res << '\n';
return;
}
B - A Reverse
题目描述:给你一个长度为\(n\)的串\(s\)(下标从\(1\)开始),和两个正整数\(lr , rs(1 \leq lr \leq rs \leq n)\),让你将串\(s\)的\([lr , rs]\)的部分翻转。
思路:根据题意模拟即可
时间复杂度:\(O(n)\)
参考代码:
std::string s, t;
void solve() {
int lr(0), rs(0);
cin >> lr >> rs >> s;
int n = s.size();
s = ' ' + s;
for (int i = 1; i < lr; ++i) t += s[i];
for (int i = rs; i >= lr; --i) t += s[i];
for (int i = rs + 1; i <= n; ++i) t += s[i];
cout << t << '\n';
return;
}
C - Product
题目描述:给你\(n\)个桶,第\(i\)个桶里面有\(L_i\)个气球,每个气球上有一个数字,再给你一个正整数\(x\),问你在每一个桶里面选一个气球使得其上的数字乘起来与\(x\)相等的方案数。
数据范围:
思路:根据数据范围显然可以暴力,但考虑到\(x\)的数据范围,显然不能对选出来的数做乘法,考虑使用dfs然后作除法,检验最终是否变成\(1\)即可,过程中可适当剪枝。
时间复杂度:\(O(\prod\limits_{i = 1}^{N}L_i)\)
参考代码:
void solve() {
int n(0), L(0), num(0);
long long x(0);
cin >> n >> x;
vector<vector<int>>a(n + 1);
for (int i = 1; i <= n; ++i) {
cin >> L;
for (int j = 1; j <= L; ++j) {
cin >> num;
a[i].push_back(num);
}
}
int res = 0;
auto dfs = [&](auto f, int idx, long long curx)->void {
if (idx == n + 1) {
if (curx == 1) ++res;
return;
}
for (auto num : a[idx]) {
if (curx % num != 0) continue;
f(f, idx + 1, curx / num);
}
};
dfs(dfs, 1, x);
cout << res << '\n';
return;
}
D - Count Interval
题目描述:给你一个数组\(A\),问你有多少个子数组的和等于\(K\)。
数据范围:\(1 \leq N \leq 2 \times 10^5 , |A_i| \leq 10^9 , |K| \leq 10^{15}\)
思路:比较经典的题目,使用前缀和+map维护一下就行了,注意答案开long long。
时间复杂度:\(O(n + nlogn) = O(nlogn)\)
参考代码:
void solve() {
map<long long, int> mp;
long long sum(0), k(0), res(0);
int n(0), a(0);
mp[0] = 1;
cin >> n >> k;
for (int i = 1; i <= n; ++i) {
cin >> a;
sum += a;
long long dx = sum - k;
if (mp.count(dx)) res += mp[dx];
mp[sum]++;
}
cout << res << '\n';
return;
}
E - \(\sum\limits_{k = 0}^{10^{100}} \lfloor \frac{X}{10^k}\rfloor\)
题目描述:
计算:\(\sum\limits_{k = 0}^{10^{100}} \lfloor \frac{X}{10^k}\rfloor\)
数据范围:\(1 \leq X < 10^{500000}\)
思路:根据数据范围发现,上式的最后一定存在值为\(0\)的项,考虑模拟1225的计算过程:
1 | 2 | 2 | 5 |
---|---|---|---|
1 | 2 | 2 | |
1 | 2 | ||
2 |
根据上表不难发现每一列就是当前位数的前缀和,考虑将每一位算出来然后再转化成十进制。
时间复杂度:\(O(n)\),\(n\)为\(X\)的位数。
参考代码:
void solve() {
string s;
vector<int>a;
cin >> s;
int n = s.size();
for (int i = n - 1; i >= 0; --i) a.push_back(s[i] - '0');
for (int i = n - 2; i >= 0; --i) a[i] += a[i + 1];
int dx(0);
for (int i = 0; i < a.size(); ++i) {
if (i == a.size() - 1 && a[i] < 10) break;
dx = a[i] / 10;
a[i] %= 10;
if (i + 1 >= a.size()) a.push_back(dx);
else a[i + 1] += dx;
}
s.clear();
n = a.size();
for (int i = n - 1; i >= 0; --i) s += a[i] + '0';
cout << s << '\n';
return;
}
作者:cherish.
出处:https://home.cnblogs.com/u/cherish-/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。