返回顶部

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\)相等的方案数。

数据范围:

\[N \geq 2\\ L_i \geq 2\\ \prod\limits_{i = 1}^{N} L_i \leq 10^5\\ 1 \leq x \leq 10^{18} \]

思路:根据数据范围显然可以暴力,但考虑到\(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;
}
posted @ 2022-01-07 22:34  cherish-lgb  阅读(139)  评论(0编辑  收藏  举报