首页 > 其他分享 >AT_abc337_d 的题解

AT_abc337_d 的题解

时间:2024-01-21 17:01:02浏览次数:32  
标签:int 题解 sum abc337 ++ flag ans times

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\) 个点,我们需要使用一个类似队列的东西来维护。

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

相关文章

  • AT_abc337_c的题解
    AT_abc337_c的题解题目大意就是给你一个数组$a=(a_1,a_2,\ldots,a_n)$,若$a_i$为$-1$,那么这个数的下标就是输出序列的开头,否侧,这个数在输出序列中排在$a_i$的下一个。思考过程从样例中不难发现:$1,2,\ldots,n$中的每一个数最多在$a$中出现一次;输出序列中的每一个......
  • P10073 [GDKOI2024 普及组] 刷野 II 的题解
    P10073[GDKOI2024普及组]刷野II的题解谨以此篇题解记录我考场上唯一通过的一题~解题思路可以考虑定义两个指针x和y,分别为左侧攻击到哪里和右侧。此时,从两侧线性想中间递推,若先打左边的代价小就打左边的,否则就打右边的。按照这个方法向中间推就可以了。Code#include<......
  • ABC337 E Bad Juice 题解
    QuestionABC337EBadJuice交互题\(n\)瓶果汁中有\(1\)瓶是坏的,现在需要把这些果汁分给\(m\)个人,每个人可以喝任意瓶,然后通过\(m\)个人的回复判断哪一瓶是坏的需要输出最小的\(m\)以及坏果汁的编号Solution\(m\)返回的结果由\(01\)构成,自然而然想到二进制,考虑......
  • 「杂题乱刷」AT_abc337_e
    题目链接题目传送门(at)题目传送门(luogu)题意简述有\(n\)瓶果汁,其中有一瓶坏的,你需要使用最少的小白鼠使得这些小白鼠能找出已经变质的果汁的编号,对于每只小白鼠,你可以给他们喝任意瓶不重复的果汁,每瓶果汁可以被平均分。解题思路妙妙构造题。思路一:拿\(n\)个小白鼠,每个小......
  • ABC337 D Cheating Gomoku Narabe 题解
    QuestionABC337DCheatingGomokuNarabe给出一个\(H\timesW\)的矩阵,由o,x,.组成,一次操作为把一个.变成o,问需要最少多少次操作使得横着或竖着有连续的\(K\)个oSolution先来考虑只有一行的情况,我们定义一个长度为\(K\)的"窗口",假设需要把这个"窗口"里面的所有......
  • CF526F Pudding Monsters 题解
    题目链接:CF或者洛谷析合树真是连续段问题的降智神器先看下题目的一些特殊性,每行每列恰好有一个棋子。考虑特殊性,\(n\timesn\)的棋盘,那么就该判断是否有\(n\)个棋子,容易观察到,也就是相当于每一行并且每一列都有一个棋子。而容易知道,这些棋子所在的行或者列拿出来应当是“......
  • ABC337
    T1:Scoreboard模拟代码实现n=int(input())st,sa=0,0foriinrange(n):x,y=map(int,input().split())st+=x;sa+=yifst<sa:print('Aoki')ifst==sa:print('Draw')ifst>sa:print('......
  • P4148 简单题 题解
    QuestionP4148简单题有一个\(n\timesn\)的棋盘,每个格子内有一个整数,初始时全部为\(0\),现在需要维护两种操作1xy将格子\(x,y\)里的数字加上\(A\)2x1y1x2y2输出\(x_1,y_1,x_2,y_2\)这个矩形内的数字和强制在线Solution因为强制在线,没法用CDQ什么乱搞,这......
  • P4747 [CERC2017] Intrinsic Interval 题解
    题目链接:IntrinsicInterval讲讲析合树如何解决这种问题,其实这题很接近析合树的板题的应用。增量法进行析合树建树时,需要用ST表预处理出\(max\)和\(min\)以便\(O(1)\)查询极差,然后线段树去维护\([l,r]\)上的极差减区间端点做差即\(diff-(r-l)\),当这玩意等于\(0\)时......
  • P8112 [Cnoi2021] 符文破译 题解
    题目传送门思路先看数据范围,我们发现两个字符串的长度最大会达到\(5\times10^7\)。这立刻打消了我用暴力的想法。于是,我选择了用KMP模式匹配,这一个能够在线性时间内判定字符串\(A\)是否是字符串\(B\)的字串,并求出字符串\(A\)在字符串\(B\)中各次出现的位置。如......