AtCoder Beginner Contest 170
Posted kanoon
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AtCoder Beginner Contest 170相关的知识,希望对你有一定的参考价值。
比赛链接:https://atcoder.jp/contests/abc170
A - Five Variables
题意
$5$ 个数中有 $1$ 个 $0$,判断是第几个。
代码
#include <bits/stdc++.h> using namespace std; int main() { for (int i = 1; i <= 5; i++) { int x; cin >> x; if (x == 0) { cout << i << " "; return 0; } } }
B - Crane and Turtle
题意
判断是否可能共有 $x$ 只鸡兔,且鸡兔的腿数加起来有 $y$ 条。($1 le x le 100, 1 le y le 100$)
题解
数据范围较小,枚举即可。
代码一
#include <bits/stdc++.h> using namespace std; int main() { int x, y; cin >> x >> y; for (int i = 0; i <= 100; i++) { for (int j = 0; j <= 100; j++) { if (i + j == x and 2 * i + 4 * j == y) { cout << "Yes" << " "; return 0; } } } cout << "No" << " "; }
代码二
#include <bits/stdc++.h> using namespace std; int main() { int x, y; cin >> x >> y; for (int i = 0; i <= x; i++) { int j = x - i; if (2 * i + 4 * j == y) { cout << "Yes" << " "; return 0; } } cout << "No" << " "; }
C - Forbidden List
题意
找出整数集中除 $n$ 个数外与 $x$ 绝对值之差最小的数。($0 le n le 100,1 le p_i le 100, 1 le x le 100$)
题解
只需构造 $[0,101]$ 即可,最后找答案的代码好像写麻烦了... 直接遍历就可以了,不过这个写法数据可以到 $10^5$ 以及回答多次询问。
代码一
#include <bits/stdc++.h> using namespace std; int main() { int x, n; cin >> x >> n; set<int> st; for (int i = 0; i <= 101; i++) st.insert(i); for (int i = 0; i < n; i++) { int t; cin >> t; st.erase(t); } auto it = st.lower_bound(x); int abs1 = abs(*it - x); int abs2 = INT_MAX; if (it != st.begin()) abs2 = abs(*(--it) - x); cout << (abs1 < abs2 ? x + abs1 : x - abs2); }
代码二
#include <bits/stdc++.h> using namespace std; int main() { int x, n; cin >> x >> n; set<int> st; for (int i = 0; i <= 101; i++) st.insert(i); for (int i = 0; i < n; i++) { int t; cin >> t; st.erase(t); } int ans = 0; int mi = INT_MAX; for (auto i : st) if (abs(i - x) < mi) mi = abs(i - x), ans = i; cout << ans << " "; }
D - Not Divisible
题意
找出 $n$ 个数中有多少个数不被其他数整除。
题解
排序后从小到大筛即可,需要标记已访问元素来优化。
代码
#include <bits/stdc++.h> using namespace std; const int MAXN = 1e6; set<int> st; map<int, bool> repeat, vis; int main() { int n; cin >> n; for (int i = 0; i < n; i++) { int x; cin >> x; if (st.count(x)) repeat[x] = true; st.insert(x); } int ans = 0; for (auto i : st) { if (vis[i]) continue; //重要的优化 for (int j = i + i; j <= MAXN; j += i) vis[j] = true; ans += !repeat[i] and !vis[i]; } cout << ans << " "; }
E - Smart Infants
题意
给出 $n$ 个人的分数和初始组别,接下来有 $q$ 个人的调遣,输出每次调遣后所有组最大分数中的最小值。
题解
维护一个最大值集合:
- 对于原集合,如果删除元素后为空或余下最大值小于删除元素,更新该集合的最大值。
- 对于新集合,如果插入元素前为空或已有最大值小于插入元素,更新该集合的最大值。
代码
#include <bits/stdc++.h> using namespace std; const int N = 2e5 + 10; int a[N]; //第i个人的分数 int mp[N]; //第i个人的组别 multiset<int> st[N]; //N个组 multiset<int> st_mx; //最大值集合 int main() { int n, q; cin >> n >> q; for (int i = 1; i <= n; i++) { int a_i, b; cin >> a_i >> b; st[b].insert(a_i); mp[i] = b, a[i] = a_i; } for (int i = 0; i < N; i++) if (st[i].size()) st_mx.insert(*st[i].rbegin()); for (int i = 0; i < q; i++) { int c, d; cin >> c >> d; st[mp[c]].erase(st[mp[c]].find(a[c])); if (st[mp[c]].size() == 0) { st_mx.erase(st_mx.find(a[c])); } else { if (*st[mp[c]].rbegin() < a[c]) { st_mx.erase(st_mx.find(a[c])); st_mx.insert(*st[mp[c]].rbegin()); } } if (st[d].size() == 0 or a[c] > *st[d].rbegin()) { if (st[d].size()) st_mx.erase(st_mx.find(*st[d].rbegin())); st_mx.insert(a[c]); } st[d].insert(a[c]); mp[c] = d; cout << *st_mx.begin() << " "; } }
以上是关于AtCoder Beginner Contest 170的主要内容,如果未能解决你的问题,请参考以下文章
AtCoder Beginner Contest 115 题解