AT_abc337_d 的题解
题目大意
给你一个 \(H \times W(H \times W \leq 2 \times 10^5)\) 的矩阵,矩阵由 o
、x
和 .
构成。存在一种操作:将一个 .
变成 o
。问在一段连续的区间内,需要进行多少次操作才可以将同一行或同一列中的连续 \(k\) 个数都变为 o
,若无法完成,输出 -1
。
思考过程
看到了可爱的 \(H \times W \leq 2 \times 10^5\),就知道这里必须使用复杂度为 \(O(HW)\) 的算法了。
考虑枚举每一列和每一行中的 \(k\) 个点是否能满足要求,并更新 ans
,由于是连续 \(k\) 个点,我们需要使用一个类似队列的东西来维护。
Code
代码中也有详细解释,但不要直接复制。
#include <bits/stdc++.h>
using namespace std;
int n, m, k;
int ans = 0x3f3f3f3f;
int sum, flag;
string str;
vector<string>s; //直接用char的话会爆空间
int main()
{
cin >> n >> m >> k;
for (int i = 0; i < n; i++)
{
cin >> str;
s.push_back(str);
}
for (int i = 0; i < n; i++) //枚举每一行
{
sum = 0, flag = 0; //sum记录该串中有多少个".",flag记录该串中有多少个"x"
for (int j = 0; j < m; j++)
{
sum += (s[i][j] == '.'), flag += (s[i][j] == 'x');
if (j >= k) //确保此时比连续的k个多
sum -= (s[i][j - k] == '.'), flag -= (s[i][j - k] == 'x');
if (j + 1 >= k && flag == 0) //是连续的k个并且没有"x"
ans = min(ans, sum);
}
}
for (int i = 0; i < m; i++) //枚举每一列
{
sum = 0, flag = 0;
for (int j = 0; j < n; j++)
{
sum += (s[j][i] == '.'), flag += (s[j][i] == 'x');
if (j >= k)
sum -= (s[j - k][i] == '.'), flag -= (s[j - k][i] == 'x');
if (j + 1 >= k && flag == 0)
ans = min(ans, sum);
}
}
if (ans == 0x3f3f3f3f)
printf("-1");
else
printf("%d", ans);
return 0;
}
标签:int,题解,sum,abc337,++,flag,ans,times
From: https://www.cnblogs.com/mgcjade/p/17978024