Acwing:过度种植(位运算枚举 Python)

 题目链接🔗:2032. 过度种植 - AcWing题库

分析:

考验思维的好题

首先这道题如果逐一矩阵去枚举的话,肯定是会超时的因为时间复杂度达到了近O(n^3)

因此这种方法行不通 所谓正难则反 我们为何不用总的面积减去重叠的面积呢?顺着这条思路

我们想到了容斥原理

容斥原理:三个集合的容斥关系公式:A∪B∪C = A+B+C - A∩B - B∩C - C∩A +A∩B∩C

推广到N维通式即当一个集合项中包含偶数项时(如上式的 A∩B)则前面符号为符号,反之为奇数项时,前置符号为正

因此 我们需要做的就是 枚举每一种重叠矩形可能出现的情景

通俗来讲 对于任意一个重叠矩形 原N个矩形中每个矩形都有两种状态 即重叠矩形的出现是有它参与的或者没有 即选或不选 因此我们想到了用二进制做优化来表示每个矩形选或者不选

还有一点需要注意 :

在每次枚举重叠矩形时 我们要找的是所有有重叠矩形的交集 即最小值 因此 下端点 (x1,y1) 应取max 上端点 (x2,y2) 应取min 这里请仔细思考清楚!

剩下的就请看代码的注释啦~ 


rect = [] # 储存矩形的左下角和右上角的坐标
res = 0
INF = float('inf')
N = int(input())
for i in range(N) :
    a,b,c,d = map(int,input().split())
    rect.append((a,d,c,b)) # 这里b和d换下位置记录,这样就能记录矩形的左下角和右上角的坐标了
    
def get(state) :
    x1,y1,x2,y2 = -INF,-INF,INF,INF 
    cnt = 0 # 记录本次一共有几个矩形参与构造重叠矩形 => 判断前置符号
    area = 0
    for i in range(N) :
        if state >> i & 1 : # 逐位判断 如果第i个矩形是被选中
            cnt += 1
            x1 = max(x1,rect[i][0])
            y1 = max(y1,rect[i][1])
            y2 = min(y2,rect[i][3])
    area = max(0,x2-x1) * max(0,y2-y1) # 这里要注意:由于有可能这种情况下 并没有产生重叠矩形 所以要和0取max
    if cnt % 2 == 0 : return -area # 如果有偶数个矩形被选中 => 前置符号为负号
    return area
            
    
for i in range(1,1<<N) : # 因为只有N个矩形,所以只需要枚举1~2^N-1这N个状态 (1<<N) = 1 * 2^N
    res += get(i)
print(res)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

UCSD.KS

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

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

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

打赏作者

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

抵扣说明:

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

余额充值