Codeforces Round 928 (Div. 4)
B题:
看每行是否有单独的一个 \(1\)。如果有的话就肯定是三角形,否则就是正方形。
主要需要注意的是这里要用 \(\rm vector<string>\) 而不能用二维的 \(\rm int\) 数组,否则在第一个输入
000
011
011
一个个输出的话是
0 11 11
0 0 0
0 0 0
也就是说在输入第二行 \(011\) 结束的时候换行才把 \(11\) 读入数组中,显然不对。
(其实题目已经规定了输入的得是字符没看到qwq)
#include <bits/stdc++.h>
void solve() {
int n;
std::cin >> n;
std::vector<std::string> s(n);
for (int i = 0; i < n; i++) std::cin >> s[i];
for (int i = 0; i < n; i++) {
if (std::count(s[i].begin(), s[i].end(), '1') == 1) {
std::cout << "TRIANGLE\n";
return;
}
}
std::cout << "SQUARE\n";
}
int main()
{
std::ios::sync_with_stdio(false), std::cin.tie(nullptr);
int t;
std::cin >> t;
while (t--) solve();
return 0;
}
C题:
如果直接暴力做的话是会超时的:
#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
int f(int x) {
int ans = 0;
while (x) {
ans += x % 10;
x /= 10;
}
return ans;
}
void solve() {
int n;
cin >> n;
i64 sum = 0;
for (int i = 1; i <= n; i++) sum += f(i);
cout << sum << "\n";
}
int main()
{
ios::sync_with_stdio(false), cin.tie(nullptr);
int t;
cin >> t;
while (t--) solve();
return 0;
}
可以观察发现性质,一个数 \(n\) 要输出的结果可以通过前一个数 \(n-1\) 的结果加上这个数本身的各位之和得出,由此考虑先预处理出结果(递推)再一起输出。
#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
const int N = 2e5 + 5;
i64 f[N];
void solve() {
int n;
cin >> n;
cout << f[n] << "\n";
}
int main()
{
ios::sync_with_stdio(false), cin.tie(nullptr);
int t;
cin >> t;
for (int i = 1; i <= N; i++) {
f[i] = f[i - 1];
int x = i;
while (x) f[i] += x % 10, x /= 10;
}
while (t--) solve();
return 0;
}
D题:
本题可以利用异或的性质。与一个数 \(n\) 相匹配的是 \(2^{31}-1\) 异或上 \(n\) 的值。我们可以用 \(\rm multiset\) 来维护满足这个性质的数,如果有就将这个数从集合中弹出,并让计数器 +1, 反之则把这个数加入集合。最后输出计数器的个数。
C++ 20 写法:
#include <bits/stdc++.h>
using i64 = long long;
void solve() {
int n;
std::cin >> n;
std::vector<int> a(n);
for (int i = 0; i < n; i++) {
std::cin >> a[i];
}
std::multiset<int> s;
int ans = n;
for (int i = 0; i < n; i++) {
if (s.contains(a[i] ^ ((1 << 31) - 1))) {
s.extract(a[i] ^ ((1 << 31) - 1));
ans--;
} else {
s.insert(a[i]);
}
}
std::cout << ans << "\n";
}
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int t;
std::cin >> t;
while (t--) {
solve();
}
return 0;
}
另一种等价的写法:
#include <bits/stdc++.h>
using namespace std;
using LL = long long;
const int INF = 0x3f3f3f3f;
const LL mod = 1e9 + 7;
const int N = 200005;
int a[N];
int main() {
int t;
scanf("%d", &t);
while (t--) {
int n;
scanf("%d", &n);
for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
multiset<int> se;
int ans = 0;
for (int i = 1; i <= n; i++) {
if (se.find(a[i] ^ INT_MAX) != se.end()) {
se.erase(se.find(a[i] ^ INT_MAX));
} else {
se.insert(a[i]);
ans++;
}
}
printf("%d\n", ans);
}
return 0;
}
E题:
思路:第一轮是 \(1\) \(3\) \(5\) \(7\)......
第二轮是 \(2\) \(6\) \(10\).......
...
在 \(1 \sim n\) 中的奇数个数为 \(\dfrac{n+1}{2}\)。看每轮中 \(k\) 是否满足在这个范围内,是的话直接输出 \(2k-1\) 乘 \(2\) 的轮数次幂,否则一直找下去
#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
void solve() {
int n, k;
cin >> n >> k;
int cnt = 0;
while (k > (n + 1) / 2) {
int x = (n + 1) / 2;
n -= x;
k -= x;
cnt++;
}
cout << (2 * k - 1) * (1 << cnt) << "\n";
}
int main()
{
ios::sync_with_stdio(false), cin.tie(nullptr);
int t;
cin >> t;
while (t--) solve();
return 0;
}

浙公网安备 33010602011771号