895 字
4 分钟
NOIp-2024-复盘&补题

成绩分析#

预期:80+30=110 SX 1= 实际:45+30=75 SX 2=

问题分析#

预期与实际差距过大,实质原因是在考场上选择了错误的做题思路,且民间数据过水,导致预期过高。也证实了考场上不能拼运气,而应该脚踏实地想正确的解决方案。

考场复盘#

考试开始后感觉T1可做,先在纸上模拟,30min后发现看错题,这时候心态有点不太稳了,但依然选择继续死磕T1。先写出几个正确性无法证明的贪心,结果没过大样例,随后在不断的推倒重想之后,选择了玄学的多次重复求正解方法,随后决定开始看T2。

T2考场怎么想的记不太清了,大体是心态不太对,打完部分分就开始想尽可能求正解,但感觉思路一直不在线。随后1h回去看T1,测样例,推结论,只到考试结束也没想出正解,考场发挥太不稳定了。

总结#

此次失利主要还是心态炸了,以及基础的不扎实,导致出现了考场无思路,状态不良好的情况。而且考场的策略也不正确,这是很大的问题。

补题记录#

  • 2025-2-21 14:27:开始补T1
  • 2025-2-21 15:09:T1 AC
  • 2025-2-21 17:14 T1题解完成

题解#

T1#

题意分析#

根据题意,考虑贪心做法,即每一位尽可能匹配上,这个策略显然正确,因为对于每一位来说,当前位匹配至多导致后面的一对无法匹配。

所以我们可以将字符串按无法交换的字符为界,分割为多个块,分别对于每一块进行操作。

一种做法为,先预处理出每一位字符所在的块的编号,并预处理出每一个块中,10的个数。然后遍历字符串,如果当前字符所在的两个块中,有相同的字符,则将两个块中对应字符的个数减一;如果没有,则将当前位的两个字符减去。过程中统计答案即可。

Code#

// #pragma GCC optimize(1, 2, 3, "Ofast", "inline")
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define int ll
#define ONLINE_JUDGE
#define MULTI_CASES
#define endl '\n'
const int MaxN = 2e5 + 100;
const int INF = 1e9;
const int mod = 212370440130137957ll;
int T = 1, N, M;
// int a[MaxN];
int cnt1[MaxN], cnt2[MaxN];
pair<int, int> q1[MaxN], q2[MaxN];
inline void Solve()
{
cin >> N;
string s1, s2, a, b;
memset(cnt1, 0, sizeof cnt1);
memset(cnt2, 0, sizeof cnt2);
memset(q1, 0, sizeof q1);
memset(q2, 0, sizeof q2);
int pos = 1;
cnt1[0] = 1;
cin >> s1 >> s2 >> a >> b;
for (int i = 1; i < N; i++)
{
if (a[i] == a[i - 1] && a[i] == '1')
{
cnt1[i] = pos;
}
else
{
pos++;
cnt1[i] = pos;
}
if (s1[i] == '1')
{
q1[cnt1[i]].first++;
}
else
{
q1[cnt1[i]].second++;
}
}
pos = 1;
cnt2[0] = 1;
for (int i = 1; i < N; i++)
{
if (b[i] == b[i - 1] && b[i] == '1')
{
cnt2[i] = pos;
}
else
{
pos++;
cnt2[i] = pos;
}
if (s2[i] == '1')
{
q2[cnt2[i]].first++;
}
else
{
q2[cnt2[i]].second++;
}
}
if (s1[0] == '1')
{
q1[cnt1[0]].first++;
}
else
{
q1[cnt1[0]].second++;
}
if (s2[0] == '1')
{
q2[cnt2[0]].first++;
}
else
{
q2[cnt2[0]].second++;
}
int sum = 0;
for (int i = 0; i < N; i++)
{
// cerr << cnt1[i] << " " << cnt2[i] << endl;
// cerr << q1[cnt1[i]].first << " " << q2[cnt2[i]].first << " ";
// cerr << q1[cnt1[i]].second << " " << q2[cnt2[i]].second << endl;
if (q1[cnt1[i]].first > 0 && q2[cnt2[i]].first > 0)
{
q1[cnt1[i]].first--;
q2[cnt2[i]].first--;
sum++;
continue;
}
if (q1[cnt1[i]].second > 0 && q2[cnt2[i]].second > 0)
{
q1[cnt1[i]].second--;
q2[cnt2[i]].second--;
sum++;
continue;
}
if (q1[cnt1[i]].first)
{
q1[cnt1[i]].first--;
q2[cnt2[i]].second--;
continue;
}
if (q1[cnt1[i]].second)
{
q1[cnt1[i]].second--;
q2[cnt2[i]].first--;
}
}
cout << sum << endl;
}
signed main()
{
#ifndef ONLINE_JUDGE
freopen(".in", "r", stdin);
freopen(".out", "w", stdout);
#endif
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
#ifdef MULTI_CASES
cin >> T;
while (T--)
#endif
Solve();
// fclose(stdin);
// fclose(stdout);
return 0;
}

T2#

NOIp-2024-复盘&补题
https://blog.introl.top/posts/noip-2024-复盘-补题/
作者
Introl
发布于
2025-02-21
许可协议
CC BY-NC-SA 4.0