返回顶部

AtCoder Beginner Contest 233题解

作者:@cherish.
课程学习内容为作者从学校的PPT处摘抄,仅供自己学习参考,若需转载请注明出处:https://www.cnblogs.com/cherish-/p/15777072.html


目前补到E题

A - 10yen Stamp

题目描述:给你两个正整数xy,求最小的非负整数n使得不等式x+10ny成立。

思路:根据题意模拟即可

时间复杂度: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(1lrrsn),让你将串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个桶里面有Li个气球,每个气球上有一个数字,再给你一个正整数x,问你在每一个桶里面选一个气球使得其上的数字乘起来与x相等的方案数。

数据范围:

N2Li2i=1NLi1051x1018

思路:根据数据范围显然可以暴力,但考虑到x的数据范围,显然不能对选出来的数做乘法,考虑使用dfs然后作除法,检验最终是否变成1即可,过程中可适当剪枝。

时间复杂度:O(i=1NLi)

参考代码:

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

数据范围:1N2×105,|Ai|109,|K|1015

思路:比较经典的题目,使用前缀和+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 - k=010100X10k

题目描述:

计算:k=010100X10k

数据范围:1X<10500000

思路:根据数据范围发现,上式的最后一定存在值为0的项,考虑模拟1225的计算过程:

1 2 2 5
1 2 2
1 2
2

根据上表不难发现每一列就是当前位数的前缀和,考虑将每一位算出来然后再转化成十进制。

时间复杂度:O(n)nX的位数。

参考代码:

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 @   cherish-lgb  阅读(147)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示