ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

AtCoder Beginner Contest 238题解

2022-02-05 22:04:33  阅读:280  来源: 互联网

标签:AtCoder 10 int 题解 sum long 238 dfs void


本场打得比较摆烂,只到E题QAQ

A - Exponential or Quadratic

题目描述:给定正整数\(n\),判断式子\(2^n > n^2\)是否成立。

思路:显然只有当n = 2 , 3 , 4时不成立

时间复杂度:\(O(1)\)

参考代码:

void solve() {
	int n;
	cin >> n;
	if (n != 2 && n != 3 && n != 4) cout << "Yes\n";
	else cout << "No\n";
	return;
}

B - Pizza

题目描述:给定一块披萨,然后给你一个数组\(A\),每次你需要转动\(a_i\)角度之后,在12点钟方向切一刀。问最终所有扇形中角度的最大值。

思路:显然让披萨转动和让刀转动等价,我们让刀转动,然后切的时候将对应角度标记为\(1\)。最后再使用双指针求最大值即可。

时间复杂度:\(O(n)\)

参考代码:

void solve() {
	int n;
	cin >> n;
	vector<int>a(n + 1, 0);
	for (int i = 1; i <= n; ++i) cin >> a[i];
	vector<int>deg(361, 0);
	deg[0] = 1; deg[360] = 1;
	int cur = 0;
	for (int i = 1; i <= n; ++i) {
		cur = (cur + a[i]) % 360;
		deg[cur] = 1;
	}
	int res = 0;
	int p = 0, q = 1;
	while (p < 360) {
		while (deg[q] == 0) ++q;
		res = max(res, q - p);
		p = q;
		q = p + 1;
	}
	cout << res << '\n';
	return;
}

C - digitnum

题目描述:定义\(f(x)\)表示与\(x\)位数相同且小于等于\(x\)的数字的个数,对于给定的\(n\),求\(\sum\limits_{i = 1}^{n}f(i)\)。

思路:根据题意显然将\(n\)按照\(10\)的幂次分段,对于每一段,如果有\(m\)个数字,那么对答案的贡献就是\(\frac{m * (m + 1)}{2}\) 。比如\(10 \sim 99\)就是从\(1 \sim 90\)的累加。

时间复杂度:\(O(log_{10}n)\)

参考代码:

void solve() {
	long long n;
	cin >> n;
	long long res = 0;
	long long p = 10, q = 1;
	const int mod = 998244353;
	while (true) {
		long long m = min(n , p - 1) - q + 1;
		m %= mod;
		res = (res + (m * (m + 1) / 2) % mod) % mod;
		if (p > n) break;
		p *= 10;
		q *= 10;
	}
	cout << res << '\n';
	return;
}

D - AND and SUM

题目描述:对于给定的\(a , s\),是否存在\(x , y\)使得以下条件成立:

  • x AND y = a
  • x + y = s

多组数据,对于每组数据若存在输出Yes,否则输出No

思路:比较明显,我们可以先通过第一个约束条件将\(x , y\)的二进制表示中必须为\(1\)的找出来,求和为\(sum\)。若\(sum> s\)则显然没有;否则\(s = s - sum\)。然后对于每一个\(x , y\)没使用的二进制位,贪心的从\(s\)中减去,若最终\(s = 0\)则存在,否则不存在。

时间复杂度:\(O(60T)\)

参考代码:

void solve() {
	long long a, s;
	cin >> a >> s;
	vector<int>cnt(60, 0);
	long long sum = 0;
	for (int i = 0; i < 60; ++i) {
		cnt[i] += (a >> i) & 1;
		if (cnt[i]) sum += 2ll << i;
	}
	if (sum > s) {
		cout << "No" << '\n';
		return;
	}
	s -= sum;
	for (int i = 59; i >= 0; --i) {
		if (cnt[i]) continue;
		long long dx = 1ll << i;
		if (dx <= s) s -= dx;
	}
	if (s == 0) cout << "Yes" << '\n';
	else cout << "No" << '\n';
	return;
}

E - Range Sums

题目描述:给你一个整数\(n\),表示有一个长度为\(n\)的正整数数组,告诉你\(q\)个条件,每个条件的形式为 lr rs,表示\(\sum\limits_{i = lr}^{rs} a_i\) 。问是否可以通过这些条件知道\(\sum\limits_{i = 1}^{n}a_i\)。若能输出Yes,否则输出No

思路:比较明显的图论题。对于每一个条件,可以根据前缀和的知识,抽象成从\(lr - 1\)到\(rs\)存在一条无向边。我们将条件读入并转化成图后,从\(0\)开始dfs。若最终能访问到第\(n\)个点,则表示可以求出题目的和式,否则不能。

时间复杂度:\(O(n)\)

参考代码:

void solve() {
	int n, q;
	cin >> n >> q;
	vector<vector<int>>graph(n + 1);
	int u, v;
	for (int i = 1; i <= q; ++i) {
		cin >> u >> v;
		graph[u - 1].push_back(v);
		graph[v].push_back(u - 1);
	}
	vector<bool>vis(n + 1, false);
	auto dfs = [&](auto dfs, int u)->void {
		if (vis[u]) return;
		vis[u] = true;
		for (auto v : graph[u]) dfs(dfs, v);
		return;
	};
	dfs(dfs, 0);
	if (vis[n]) cout << "Yes" << '\n';
	else cout << "No" << '\n';
	return;
}

标签:AtCoder,10,int,题解,sum,long,238,dfs,void
来源: https://www.cnblogs.com/cherish-/p/15864900.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有