Acwing(春季每日一题)阻挡广告牌 II

还 请 各 位 大 佬 批 评 指 正 O r z \Large\color{Green}{还请各位大佬批评指正Orz} Orz

题目描述

奶牛贝茜曾经从农场中向外看去,可以看到两个刊登着美味的牛饲料广告的广告牌,这令她非常满意。

不幸的是,其中一个广告牌最近已更新,现在刊登着广告“农民拉里的割草机”。

但是贝茜可不喜欢割草机,这些割草机只会把她爱吃的草割的一干二净。

幸运的是,剩下的牛饲料广告牌位于割草机广告牌的前面,有可能将其遮挡住。

贝茜希望这个讨厌的割草机广告牌能够完全从自己的视线中消失,并为此制定了一个冒险计划。

她计划从谷仓里偷一个大的矩形防水布,并在深夜偷偷溜走,用它覆盖割草机广告牌的其余部分,使得她能完全看不到割草机广告牌。

给定两个广告牌的位置,请帮助贝茜计算她所需要的防水布的最小面积。

由于谷仓中只有矩形的防水布,因此贝茜发现为了将割草机广告牌完全遮盖,所需的防水布面积可能会大于割草机广告牌的裸露面积,如下例所示。

防水布在放置时,其边必须与广告牌的边平行,即不能倾斜放置。

输入格式

第一行包含四个整数 x 1 , y 1 , x 2 , y 2 x_1,y_1,x_2,y_2 x1,y1,x2,y2,其中 ( x 1 , y 1 ) (x_1,y_1) (x1,y1) ( x 2 , y 2 ) (x_2,y_2) (x2,y2) 表示割草机广告牌的左下角和右上角坐标。

第二行按照如上形式,包含四个整数,表示牛饲料广告牌的左下角和右上角坐标。

牛饲料广告牌可能完全遮盖了割草机广告牌,或部分遮盖了割草机广告牌,也可能完全没有遮盖割草机广告牌。

输出格式

输出用来遮盖割草机广告牌的防水布的最小面积。

数据范围

− 1000 ≤ x 1 , y 1 , x 2 , y 2 ≤ 1000 −1000≤x_1,y_1,x_2,y_2≤1000 1000x1,y1,x2,y21000

输入样例
2 1 7 4
5 -1 10 3
输出样例
15
样例解释

虽然牛饲料广告牌遮盖住了割草机广告牌的右下角的一部分,但这并没有起到作用。

想要完全遮盖割草机广告牌,仍然需要一块和它尺寸相同的防水布。


算法

(暴力枚举) O ( n 2 ) O(n^2) O(n2)

我们继续延续一下阻挡广告牌 I,即上一道题目。

  • 将割草机广告牌所覆盖的格子全部染色成1
  • 将牛饲料广告牌所覆盖的格子全部染色成2
  • 再将所有格子为1的点放入一个数组里面去
  • 令我们的min_x = INF, max_x = -INF, min_y = INF, max_y = -INF;其中 I N F = + ∞ INF=+\infty INF=+
  • 找出所有点的 x x x的最小值和最大值(min_x = INF, max_x = -INF), y y y的最小值和最大值(min_y = INF, max_y = -INF)(即一个完整的矩形)
  • 最后答案就是(max_x - min_x + 1) * (max_y - min_y + 1)

具体看下图的思路:(字有点丑,还请多多包涵)

在这里插入图片描述

时间复杂度 O ( n 2 ) O(n^2) O(n2)
C++ 代码
#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

typedef pair<int, int> PII;

const int N = 2010;

int a[N][N];//地图
PII q[N * N];//割草机广告牌所有点的集合
int x, y;
int cnt;

int main()
{
    int x1, y1, x2, y2;
    
    int c = 1;
    for (int i = 0; i < 2; i ++ )
    {
        scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
        
        x1 += 1000, y1 += 1000, x2 += 1000, y2 += 1000;//加上偏移量使得坐标为非负值
        
        if (i == 1)//若为割草机广告牌,则染色成1,否则染色成2
            c = 2;
            
        for (int j = x1; j < x2; j ++ )//将广告牌所覆盖的区域染色
            for (int k = y1; k < y2; k ++ )
                a[j][k] = c;
    }
    
    for (int i = 0; i < 2010; i ++ )//将所有染色为1的点存入q数组中
        for (int j = 0; j < 2010; j ++ )
            if (a[i][j] == 1)
                q[cnt ++ ] = {i, j};
         
    /*最小值初始化为正无穷,最大值初始化为负无穷*/
    int min_x = N, max_x = -N, min_y = N, max_y = -N;
    /*找出其中最小的一个矩阵的(x,y)的两个端点值*/
    for (int i = 0; i < cnt; i ++ )
    {
        x = q[i].first, y = q[i].second;
        min_x = min(min_x, x);
        max_x = max(max_x, x);
        min_y = min(min_y, y);
        max_y = max(max_y, y);
    }

    int res = (max_x - min_x + 1) * (max_y - min_y + 1);//计算面积
    /*若面积为负值,则证明不用覆盖,牛饲料广告牌已经完全遮盖了割草机广告牌*/
    printf("%d", res > N * N ? 0 : res);
    
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Nie同学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值