Codeforces Round 1010 (Div. 2, Unrated)
A. Binary Matrix
题目大意
给你一个01矩阵,如果矩阵的所有行列异或和都是0则是好矩阵,问要让矩阵变好的最小操作次数
解题思路
行的总修改次数和列的总修改次数二者取大即可
代码实现
#include <bits/stdc++.h>
using i64 = long long;
const int MOD = 1e9 + 7;
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(0);
std::cout.tie(0);
int tt;
std::cin >> tt;
while (tt--) {
int n, m;
std::cin >> n >> m;
std::vector<std::string> g(n);
for (int i = 0; i < n; i++) {
std::cin >> g[i];
}
int ans1 = 0, ans2 = 0;
for (int i = 0; i < n; i++) {
int cnt = 0;
for (int j = 0; j < m; j++) {
cnt += g[i][j] == '1';
}
ans1 += cnt % 2;
}
for (int j = 0; j < m; j++) {
int cnt = 0;
for (int i = 0; i < n; i++) {
cnt += g[i][j] == '1';
}
ans2 += cnt % 2;
}
std::cout << std::max(ans1, ans2) << "\n";
}
}
B. Floor or Ceil
题目大意
给你一个数x,可以执行n次/2向下取整和m次/2向上取整,问操作完之后可能的最大最小值
解题思路
因为每次操作都会导致变小两倍左右,所以中间穿插向上取整操作是没有意义的,因此只需要把两个操作分开执行完,按照先后顺序就能得到最大最小值
代码实现
#include <bits/stdc++.h>
using i64 = long long;
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(0);
std::cout.tie(0);
int tt;
std::cin >> tt;
while (tt--) {
int x, n, m;
std::cin >> x >> n >> m;
int x1 = x, n1 = n, m1 = m;
while (m1-- && x1 > 1) {
x1++;
x1 >>= 1;
}
while (n1-- && x1) {
x1 >>= 1;
}
int x2 = x, n2 = n, m2 = m;
while (n2-- && x2) {
x2 >>= 1;
}
while (m2-- && x2 > 1) {
x2++;
x2 >>= 1;
}
std::cout << x1 << " " << x2 << "\n";
}
}
C. Math Division
题目大意
给你一个数x,等概率随机执行/2向下取整和/2向上取整,问把x变成1的期望是多少,对答案模1e9+7
解题思路
首先去掉最高位,最高位一定是1,并且可以贡献基础操作次数n-1。接着考虑x的奇偶性,当x是偶数的时候,向上向下是等价的,直接/2即可,当二进制数是奇数的时候最低位的1会导致额外的期望次数,可以通过累加每一位的影响来计算
代码实现
#include <bits/stdc++.h>
using i64 = long long;
const int MOD = 1e9 + 7;
const int inv2 = 5e8 + 4;
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(0);
std::cout.tie(0);
int tt;
std::cin >> tt;
while (tt--) {
int n;
std::cin >> n;
std::string s;
std::cin >> s;
std::reverse(s.begin(), s.end());
s.pop_back();
i64 ans = 0;
for (auto ch : s) {
ans = (ans + (ch == '1')) * inv2 % MOD;
}
std::cout << (ans + n - 1) % MOD << "\n";
}
}

浙公网安备 33010602011771号