Codeforces Round #644 (Div. 3)
比赛链接:https://codeforces.com/contest/1360
A - Minimal Square
题意
计算能包含两个 $a \times b$ 矩形的最小正方形的面积。
题解
将两个矩形的较短边拼在一起即可。
代码
#include <bits/stdc++.h> using namespace std; void solve() { int a, b; cin >> a >> b; if (a > b) swap(a, b); int mx = max(a + a, b); cout << mx * mx << "\n"; } int main() { int t; cin >> t; while (t--) solve(); }
B - Honest Coach
题意
将 $n$ 个数分为两组,使得一组的最大值与另一组的最小值相差最小。
题解
将 $n$ 个数排序后从相差最小的两个数间分开即可。
代码
#include <bits/stdc++.h> using namespace std; void solve() { int n; cin >> n; int a[n] = {}; for (int i = 0; i < n; i++) cin >> a[i]; sort(a, a + n); int mi = INT_MAX; for (int i = 1; i < n; i++) mi = min(mi, a[i] - a[i - 1]); cout << mi << "\n"; } int main() { int t; cin >> t; while (t--) solve(); }
C - Similar Pairs
题意
将偶数个数两两配对,要求配对的数具有相同的奇偶性或相差为 $1$ 。
题解
如果奇偶数均有偶数个则它们内部两两配对即可,否则找出一对相差为 $1$ 奇偶数配对,余下的奇偶数个数又均为偶数。
代码
#include <bits/stdc++.h> using namespace std; void solve() { int n; cin >> n; vector<int> odd; map<int, int> even; for (int i = 0; i < n; i++) { int x; cin >> x; if (x % 2) odd.push_back(x); else even[x]++; } bool flag = false; if (odd.size() % 2) { for (auto x : odd) if (even[x - 1] or even[x + 1]) flag = true; } else flag = true; cout << (flag ? "YES" : "NO") << "\n"; } int main() { int t; cin >> t; while (t--) solve(); }
D - Buying Shovels
题意
要买刚好 $n$ 个铲子,有 $k$ 种包装的铲子,每种包装内的铲子数量分别为 $1{\sim}k$,只能挑一种包装购买,计算同一包装最少需要买多少个。
题解
在 $n$ 的因子中找小于等于 $k$ 的最大因子,$n$ 除以该最大因子即为最少个数。
代码
#include <bits/stdc++.h> using namespace std; void solve() { int n, k; cin >> n >> k; int ans = n; for (int i = 1; i * i <= n; i++) { if (n % i == 0) { if (i <= k) ans = min(ans, n / i); if (n / i <= k) ans = min(ans, i); } } cout << ans << "\n"; } int main() { int t; cin >> t; while (t--) solve(); }
E - Polygon
题意
$n \times n$ 网格的最上边一排和最左边一列外各有 $n$ 门大炮,大炮可向网格内发射 $1$,每次发射的 $1$ 遇到边界或 $1$ 停下来,判断是否存在某种发射顺序可以得到给出的网格。
题解
因为大炮的位置在左和上,所以每个非右下边界的 $1$ 右或下方一定有一个 $1$ 。
代码
#include <bits/stdc++.h> using namespace std; void solve() { int n; cin >> n; char MP[n][n] = {}; for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) cin >> MP[i][j]; bool flag = true; for (int i = 0; i < n - 1; i++) for (int j = 0; j < n - 1; j++) if (MP[i][j] == '1' and MP[i + 1][j] != '1' and MP[i][j + 1] != '1') flag = false; cout << (flag ? "YES" : "NO") << "\n"; } int main() { int t; cin >> t; while (t--) solve(); }
F - Spy-string
题意
给出 $n$ 个字符串,找出一个字符串,要求该字符串与每个字符串相差最多一个字母。
题解
记录每个字符串的衍生字符串,被衍生了 $n$ 次的字符串即为答案。
代码
#include <bits/stdc++.h> using namespace std; void solve() { int n, m; cin >> n >> m; map<string, int> mp; for (int i = 0; i < n; i++) { string s; cin >> s; set<string> st; for (int j = 0; j < m; j++) { char t = s[j]; for (int k = 0; k < 26; k++) { if (t - k >= 'a') { s[j] = t - k; st.insert(s); } if (t + k <= 'z') { s[j] = t + k; st.insert(s); } } s[j] = t; } for (auto i : st) ++mp[i]; } for (auto i : mp) { if (i.second == n) { cout << i.first << "\n"; return; } } cout << -1 << "\n"; } int main() { int t; cin >> t; while (t--) solve(); }
G - A/B Matrix
题意
构造一个 $n \times m$ 的 $01$ 矩阵,使得每行有 $a$ 个 $1$,每列有 $b$ 个 $1$ 。
题解
所有行的 $1$ 的个数:$n \times a$
所有列的 $1$ 的个数:$m \times b$
如果存在满足要求的 $01$ 矩阵,二者必须相等,之后按行或列贪心构造即可。
代码
#include <bits/stdc++.h> using namespace std; void solve() { int n, m, a, b; cin >> n >> m >> a >> b; if (n * a != m * b) { cout << "NO" << "\n"; return; } bool MP[n][m] = {}; int col = 0; for (int row = 0; row < n; row++) { for (int i = 0; i < a; i++) { MP[row][col] = '1'; if (++col == m) col = 0; } } cout << "YES" << "\n"; for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) cout << MP[i][j]; cout << "\n"; } } int main() { int t; cin >> t; while (t--) solve(); }
H - Binary Median
题意
$0 \sim 2^m - 1$ 中去掉 $n$ 个数后第 $\lfloor \frac{k - 1}{2} \rfloor$ 个数是多少(即余下的 $k$ 个数的中位数)。
题解
对于中位数来说,如果去掉的数的值小于等于它自身,那么中位数的值会向右偏移一,最小的中位数即为刚开始去掉 $n$ 个最大的数,从小到大统计是否有值小于等于中位数,同时更新中位数的值即可。
代码
#include <bits/stdc++.h> using ll = long long; using namespace std; void solve() { int n, m; cin >> n >> m; ll ans = ((1LL << m) - n - 1) / 2; ll a[n] = {}; for (int i = 0; i < n; i++) { string s; cin >> s; a[i] = bitset<64>(s).to_ullong(); } sort(a, a + n); for (auto i : a) ans += (i <= ans); cout << bitset<64>(ans).to_string().substr(64 - m) << "\n"; } int main() { int t; cin >> t; while (t--) solve(); }