20250714Div2比赛题解
2025/7/13大约 3 分钟
T1
原题CF903A。暴力枚举小鸡块大鸡块的盒数,然后打表得到六种不能的方案。
打表程序伪代码:
bool a[101]
for(int i=0; i<=100/3; i++) {
for(int j=0; j<=100/7; j++) {
a[i*3+j*7]=true
}
}
for(int i=1; i<=100; i++) {
if(!a[i]) {
cout << i << endl;
}
}std:
// CF903A
#include <stdio.h>
int main() {
int n, m;
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
scanf("%d", &m);
if (m == 1 || m == 2 || m == 4 || m == 5 || m == 8 || m == 11)
puts("NO");
else
puts("YES");
}
}T2
原题CF635A暴力枚举即可过本题。
如果要优化,就用一下矩阵的前缀和即可。
暴力 std:
// CF635A
#include <bits/stdc++.h>
using namespace std;
int mp[15][15];
int main()
{
int r, c, n, k;
cin >> r >> c >> n >> k;
for (int i = 1; i <= n; i++) {
int pr, pc;
cin >> pr >> pc;
mp[pr][pc]++;
}
int ans = 0;
for (int x1 = 1; x1 <= r; x1++) {
for (int y1 = 1; y1 <= c; y1++) {
for (int x2 = x1; x2 <= r; x2++) {
for (int y2 = y1; y2 <= c; y2++) {
int sum = 0;
for (int x3 = x1; x3 <= x2; x3++) {
for (int y3 = y1; y3 <= y2; y3++) {
if (mp[x3][y3]) {
sum++;
}
}
}
if (sum >= k)
ans++;
}
}
}
}
cout << ans << endl;
}优化 std:
// CF2094D
#include <bits/stdc++.h>
using namespace std;
int mp[15][15];
int main()
{
int r, c, n, k;
cin >> r >> c >> n >> k;
for (int i = 1; i <= n; i++) {
int pr, pc;
cin >> pr >> pc;
mp[pr][pc]++;
}
int ans = 0;
for (int i = 1; i <= r; i++) {
for (int j = 1; j <= c; j++) {
mp[i][j] += mp[i - 1][j] + mp[i][j - 1] - mp[i - 1][j - 1];
}
}
for (int x1 = 1; x1 <= r; x1++) {
for (int Y1 = 1; Y1 <= c; Y1++) {
for (int x2 = x1; x2 <= r; x2++) {
for (int y2 = Y1; y2 <= c; y2++) {
if (mp[x2][y2] - mp[x1 - 1][y2] - mp[x2][Y1 - 1] + mp[x1 - 1][Y1 - 1] >= k)
ans++;
}
}
}
}
cout << ans << endl;
}T3
原题CF2117C。这题维护两个set就行。首先考虑到一点,如果当前段已经符合抽象分割了,那么就应该分割,使得后面有尽可能多的元素用来分割。然后我们注意到,抽象分割具有传递性,也就是如果
既然这样,我们只要维护两个set,第一个set set set相等,则这里就可以分段。
std:
// CF2117C
#include <bits/stdc++.h>
using namespace std;
set<int> cur, global;
int main()
{
int T;
cin >> T;
while (T--) {
int n, ans = 0;
cur.clear();
global.clear();
cin >> n;
int a[n + 1];
for (int i = 1; i <= n; i++) {
cin >> a[i];
}
for (int i = 1; i <= n; i++) {
global.insert(a[i]);
cur.insert(a[i]);
if (global.size() == cur.size()) {
ans++;
cur.clear();
}
}
if (ans == 0)
cout << 1 << endl;
else
cout << ans << endl;
}
return 0;
}T4
原题CF2094D。这题把两个序列都按照连续的L和R分段。然后,如果第一段所代表的元素就不一样,那么它结果一定是NO。对于剩下的一个一定是L和R交错的序列,我们统计个数,如果NO。
// CF2094D
#include <bits/stdc++.h>
#include <cstring>
using namespace std;
constexpr int MAX_N = 2e5 + 1;
int ps[MAX_N], pp[MAX_N];
int pspt = 1, pppt = 1;
int main()
{
int T;
cin >> T;
while (T--) {
// Reset
memset(ps, 0, sizeof(ps));
memset(pp, 0, sizeof(pp));
pspt = 1;
pppt = 1;
// Input
string p, s;
cin >> p >> s;
if (p[0] != s[0]) {
cout << "NO" << endl;
continue;
}
// Execute
pp[pppt] = 1;
for (int i = 1; i < p.size(); i++) {
if (p[i] != p[i - 1]) {
pppt++;
pp[pppt] = 1;
} else {
pp[pppt]++;
}
}
ps[pspt] = 1;
for (int i = 1; i < s.size(); i++) {
if (s[i] != s[i - 1]) {
pspt++;
ps[pspt] = 1;
} else {
ps[pspt]++;
}
}
// for (int i = 1; i <= pppt; i++) {
// cerr << pp[i] << ',';
// }
// cerr << endl;
// for (int i = 1; i <= pspt; i++) {
// cerr << ps[i] << ',';
// }
// cerr << endl;
if (pppt != pspt) {
cout << "NO" << endl;
continue;
}
for (int i = 1; i <= pppt; i++) {
if (ps[i] >= pp[i] && ps[i] <= 2 * pp[i]) {
continue;
} else {
cout << "NO" << endl;
goto nxt_loop;
}
}
cout << "YES" << endl;
nxt_loop:;
}
return 0;
}