题面链接:https://codeforces.com/contest/2272/problem/B
题面大意:给一个 `2 × n` 网格,每格最多一只青蛙,且每列至少一只。你可以先删除最少数量 `k` 的青蛙,然后让剩余青蛙同时向上下左右跳一格,最终保持每一行、每一列的青蛙总数不变。求最小的 `k`。
题目思路:由于要求所有青蛙同时跳一格后,最终每行、每列的青蛙总数不变,并且每只青蛙只能上下左右选一个方向跳,那么为了符合要求,从上往下跳的青蛙数量必须等于从下往上跳的青蛙数量;左右方向同理,也就是对每一条相邻列之间的边界,从左往右跳的数量必须等于从右往左跳的数量。除此之外没有其他情况,所以可以把这些移动看成每两只青蛙一一配对。因此在删除 `k` 只青蛙后,最后剩余青蛙的数量必然是偶数。反过来,剩余青蛙数量为偶数时,也一定可以通过上下方向配对和左右方向配对构造出合法跳跃方案,所以"剩余青蛙数为偶数"是充要条件。也就是说,初始青蛙数量为偶数时答案为 `0`;初始数量为奇数时,只需要删除1只青蛙使剩余数量变成偶数,答案为 `1`。
时间复杂度:O(n)
代码如下:
cpp
#include <bits/stdc++.h>
using namespace std;
#define endl "\n"
using ll = long long;
using ld = long double;
/*
https://codeforces.com/contest/2272/problem/B
Div.2 CF 1130B题(构造,贪心)
题面大意:给一个 `2 × n` 网格,每格最多一只青蛙,且每列至少一只。你可以先删除最少数量 `k` 的青蛙,
然后让剩余青蛙同时向上下左右跳一格,最终保持每一行、每一列的青蛙总数不变。求最小的 `k`。
题目思路:由于要求所有青蛙同时跳一格后,最终每行、每列的青蛙总数不变,并且每只青蛙只能上下左右选一个方向跳,
那么为了符合要求,从上往下跳的青蛙数量必须等于从下往上跳的青蛙数量;左右方向同理,也就是对每一条相邻列之间的边界,
从左往右跳的数量必须等于从右往左跳的数量。除此之外没有其他情况,所以可以把这些移动看成每两只青蛙一一配对。
因此在删除 `k` 只青蛙后,最后剩余青蛙的数量必然是偶数。反过来,剩余青蛙数量为偶数时,
也一定可以通过上下方向配对和左右方向配对构造出合法跳跃方案,所以"剩余青蛙数为偶数"是充要条件。
也就是说,初始青蛙数量为偶数时答案为 `0`;初始数量为奇数时,只需要删除1只青蛙使剩余数量变成偶数,答案为 `1`。
*/
//时间复杂度:O(n)
void solve()
{
int n;
cin >> n;
vector<string> s(2);//初始化s大小为2
for (int i = 0; i < 2; i++)
{
cin >> s[i];
}
int cnt = 0;
for (int i = 0; i < n; i++)
{
if (s[0][i] == 'f')//统计第一行青蛙数量
{
cnt++;
}
if (s[1][i] == 'f')//统计第二行青蛙数量
{
cnt++;
}
}
cout << cnt % 2 << endl;//对2取余就行,如果是偶数就是0,是奇数就是1
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int T;
cin >> T;
while (T--)
{
solve();
}
return 0;
}