window.cnblogsConfig = {//可以放多张照片,应该是在每一个博文上面的图片,如果是多张的话,那么就随机换的。 homeTopImg: [ "https://i.loli.net/2019/08/02/5d440029af8e994539.png" ], }

AT_abc337_d 的题解

AT_abc337_d 的题解

题目大意

给你一个 \(H \times W(H \times W \leq 2 \times 10^5)\) 的矩阵,矩阵由 ox. 构成。存在一种操作:将一个 . 变成 o。问在一段连续的区间内,需要进行多少次操作才可以将同一行或同一列中的连续 \(k\) 个数都变为 o,若无法完成,输出 -1

思考过程

看到了可爱的 \(H \times W \leq 2 \times 10^5\),就知道这里必须使用复杂度为 \(O(HW)\) 的算法了。

考虑枚举每一列和每一行中的 \(k\) 个点是否能满足要求,并更新 ans,由于是连续 \(k\) 个点,我们需要使用一个类似队列的东西来维护,维护当前的列或者行中的连续 \(k\) 个点中有多少个 . 和多少个 x,有多少个 . 就是当前的最优答案,如果当前 \(k\) 个字符中有 x,就证明当前 \(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; }

__EOF__

本文作者mgcjade
本文链接https://www.cnblogs.com/mgcjade/p/17978024.html
关于博主:蒟蒻一枚,I AK IOI!(不可能的)
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   mgcjade  阅读(17)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示