首页 > 其他分享 >[COCI2021-2022#6] Zemljište

[COCI2021-2022#6] Zemljište

时间:2023-10-20 09:33:28浏览次数:37  
标签:COCI2021 边界 int 矩阵 复杂度 样例 权值 Zemlji te

[COCI2021-2022#6] Zemljište

题目描述

有一块地,大小为 $r \times s$,$\rm Matej$ 想买下它。这块地每个 $1\times1$ 的正方形都有不同的价格。

设一片非空子矩阵价格总和为 $m$,则这片子矩阵的权值为 $|m-a|+|m-b|$,您需要找到最小权值的子矩阵。

您只需要输出最小权值即可。

输入格式

第一行包含四个正整数 $r$, $s$ , $a$ 和 $b$ 。

下面 $r$ 行,第 $i$ 行,有 $s$ 个正整数,第 $j$ 个数表示 $c_{i,j}$,表示价格。

输出格式

一行一个整数 $v$,表示最小非空子矩阵的权值。

样例 #1

样例输入 #1

2 2 10 10
1 3
4 1

样例输出 #1

2

样例 #2

样例输入 #2

3 2 3 4
1 9
1 1
8 1

样例输出 #2

3

样例 #3

样例输入 #3

3 4 5 3
1 1 1 1
9 6 7 6
8 1 9 7

样例输出 #3

2

提示

样例解释 2

如图,总价格是$1 + 1 = 2$,这块地的权值是 $|3−2| + |4−2| =3$。

数据范围:

对于 $14\%$ 的数据:$1\le r,s\le20$

对于 $28\%$ 的数据:$1\le r,s\le100$

对于 $100\%$ 的数据:$1\le r,s\le500$,$1\le a,b,c_{i,j}\le10^9$

本题分值与 COCI 2021-2022#6 分值相同,满分 $70$ 分

 

解题思路

  很明显最直接的做法是枚举处所有的子矩阵,然后通过前缀和算出子矩阵的和 $m$,从而得到 $|m-a| + |m-b|$,取所有情况的最小值即可。为此我们需要枚举左上角和右下角的坐标来确定子矩阵,所以时间复杂度为 $O(n^4)$,明显超时。

  由于 $n$ 的最大取值是 $500$,所以应该要把时间复杂度控制在 $O(n^3)$ 级别,而 $O(n^3 \log{n})$ 大概率会超时因此不行。一般来说要枚举子矩阵都会想到枚举左上角 $(x_1,x_2)$ 和右下角 $(x_2, y_2)$,这里再提供另外一种思路,即枚举子矩阵的上边界 $x_1$,下边界 $x_2$,左边界 $y_1$,右边界 $y_2$。然而这样做时间复杂度还是 $O(n^4)$,由于要把复杂度控制在 $O(n^3)$,意味着我们只能枚举三个边界,另外一个边界通过 $O(1)$ 来得到。

  不妨假设枚举上边界 $x_1$,下边界 $x_2$ 和右边界 $y_2$,这时左边界 $y_1$ 的选择就有 $y_1 \in [1, y_2]$,在这些选择中要确定使得 $|m-a| + |m-b|$ 最小的那个。这时我们就要观察 $|m-a| + |m-b|$ 这个式子了,很明显只有 $m$ 会影响式子的结果。不妨假设 $a < b$(否则交换 $a$ 和 $b$ 即可),当 $m \in [a, b]$ 时,结果能够取到最小值 $b-a$。否则如果 $m < a$,式子结果就是 $a + b - 2m$,因此要让 $m$ 尽可能接近 $a$(在 $m < a$ 的前提下),才能让结果尽可能小。同理,当 $m > b$,式子结果就是 $2m - a - b$,应该让 $m$ 尽可能接近 $b$ 结果才能变小。

  另外由于矩阵中的元素均为正整数,因此随着 $y_1$ 往右移动子矩阵的和就会减小,因此满足单调性,可以二分出满足 $m \leq a$ 的最大的 $m$ 所对应的 $y_1$,假设为 $u$;二分出满足 $m \geq b$ 的最小的 $m$ 所对应的 $y_1$,假设为 $v$。那么就可以对这两个子矩阵 $(x_1, u, x_2, y_2)$ 和 $(x_1, v, x_2, y_2)$ 分别计算式子的结果取最小值。这种做法的时间复杂度是 $O(n^3 \log{n})$。

  然而我们还需要优化到 $O(n^3)$。事实上随着 $y_2$ 往右移动,$u$ 和 $v$ 也最会往右移动。否则 $y_2$ 往右移动得到 $y_2'$,$u$ 会往左移动得到 $u'$,子矩阵 $(x_1, u', x_2, y_2')$ 的和满足不超过 $a$ 的最大值,意味着子矩阵 $(x_1, u', x_2, y_2)$ 的和也不超过 $a$,且比子矩阵 $(x_1, u, x_2, y_2)$ 的和更接近 $a$,这就与之前的假设矛盾了。同理分析 $v$。因此这里我们可以用双指针来优化。

  AC 代码如下,时间复杂度为 $O(n^3)$:

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;

const int N = 510;

LL s[N][N];

LL get(int x1, int y1, int x2, int y2) {
    return s[x2][y2] - s[x1 - 1][y2] - s[x2][y1 - 1] + s[x1 - 1][y1 - 1];
}

int main() {
    int n, m, a, b;
    scanf("%d %d %d %d", &n, &m, &a, &b);
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            scanf("%lld", &s[i][j]);
            s[i][j] += s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1];
        }
    }
    LL ret = 1e18;
    for (int i = 1; i <= n; i++) {
        for (int j = i; j <= n; j++) {
            for (int k = 1, u = 1, v = 1; k <= m; k++) {
                while (u < k && get(i, u, j, k) > a) {
                    u++;
                }
                LL t = get(i, u, j, k);
                ret = min(ret, abs(t - a) + abs(t - b));
                while (v < k && get(i, v + 1, j, k) >= b) {
                    v++;
                }
                t = get(i, v, j, k);
                ret = min(ret, abs(t - a) + abs(t - b));
            }
        }
    }
    printf("%lld", ret);
    
    return 0;
}

 

参考资料

  P8343 题解:https://www.luogu.com.cn/blog/xiaolu12356/solution-p8343 

标签:COCI2021,边界,int,矩阵,复杂度,样例,权值,Zemlji,te
From: https://www.cnblogs.com/onlyblues/p/17776269.html

相关文章

  • jfinal框架下,连接国产达梦数据库,抛出SocketTimeoutException异常
    公司为政府开发项目,主框架选择springboot,orm框架使用jfinal。数据库为国产达梦数据库写统计类服务时,通常sql运行时间会比较久,超过10s的sql一定会报SocketTimeoutException异常 尝试使用原生jdbc创建连接,运行sql毫无问题。遂检查连接池设置。jfinal使用druid连接池网上搜索......
  • WPF TextBox按回车键执行
    如果界面上只有一个要执行的命令时,可以直接把某个Button的IsDefault设置为True就可以。如果界面上有多个不同的执行命令的话,可以用下面的InputBindings,不同的输入框绑定不同的Command即可。<TextBoxText="{BindingProgressName,UpdateSourceTrigger=PropertyChanged}"S......
  • [ABC267F] Exactly K Steps
     多次询问给出x,给出任意点y满足dis(x,y)==m  以直径端点为根,dfs可以发现至少有一个y在这个路径上https://www.luogu.com.cn/record/130467795......
  • 一个更复杂的 PHP 代码示例,我将展示一个购物车系统的基本实现,它包括商品类、购物车类
    一个更复杂的PHP代码示例,我将展示一个购物车系统的基本实现,它包括商品类、购物车类和一些基本的操作方法。<?php//定义商品类classProduct{private$name;private$price;publicfunction__construct($name,$price){$this->name=$name;$this->pri......
  • 如何学习 Flutter?这篇文章帮你搞定
    先来看看全球开发者的一个使用情况91%的开发者认为Flutter缩短了构建和发布应用程序的时间85%的开发者认为Flutter使他们的应用程序比以前更漂亮85%的人认为Flutter使他们的应用比以前能在更多的平台上发布再来看看Flutter的定义Flutter是谷歌的移动UI框架,它可以快速......
  • AtCoder Regular Contest 167——B - Product of Divisors
    题目很明显,给定 所有因数的积不断除以最多能除几次。首先,很容易发现,对于每一对因子,都可以对答案得出B的贡献,设A的因子数目为n。将A进行质因数分解,PBa1,PBa2,PBa3……PBam,那么因数个数就是质因子加一的乘积。那么因子对数也就是前者一半。答案就是B乘因子对数除以二注意此处......
  • 解决:Exception: URL fetch failure on https://storage.googleapis.com/tensorflow/tf
    首次装载IMDB数据集时可能会出现的错误。解决方案:1、先将数据集单独下载下来:datasets/imdb.npz·黄健/keras-datasets-Gitee.com2、将其复制到 ~/.keras/dataset目录下:cpimdb.npz ~/.keras/dataset ......
  • IsHitTestVisible
    定义在UIElement类,几乎所有WPF元素都有此属性,默认值True。设置成False后,控件及其子控件都不能响应鼠标,如IsMouseOver,Click,MouseEnter,MouseLeftButtonUp等。假设通过触发器设置当鼠标经过控件表面时,背景色变成红色,但是IsHitTestVisible被设置成false后,鼠标经过时,控件不会发......
  • Educational Codeforces Round 149 (Rated for Div. 2) C. Best Binary String
    给一个字符串\(s\)包含\(0,1,?\)。定义一个\(01\)串\(s\)的\(cost\)为:选择\(s\)的任意一个子段\([l,r]\)并\(reverse\)。将\(s\)变为一个非降序序列时的\(reverse\)最小次数即\(cost\)。你可以让\(s\)的\(?\)换成\(0/1\),使新\(s\)的\(cost\)......
  • latexmk+make+条件编译一键编译论文生成 明评版/盲评版 单面版/双面版
    用latexmk+make编译latex项目假设latex项目的目录结构如下:.├──build│  ├──aux│  ├──各种临时文件│  └──release│  ├──thesis.pdf│  └──thesis.synctex.gz├──data│  ├──abstract.tex│  ├─......