P1696 [USACO18JAN] Blocked Billboard II B 题解
怎么题解区都是暴力,来点不一样的做法。
第二个矩形在第一个矩形上方,那么它覆盖的有效度只有以下可能:
- 第二个矩形对结果没有任何贡献,题面中的大布仍然要盖住整个第一个矩形。
- 第二个矩形成功盖住了第一个矩形的一条边,大布只需要盖住剩下的面积。
- 第二个矩形很大,能直接盖住第一个矩形。那么此时不需要大布,那就输出
0。
可以看到,大布面积不需要达到第一个矩形那么大的可能性比较小,可以直接从后到前判断当前两个矩形的状态,然后输出对应的答案。
1. 第二个矩形完全包含第一个矩形
题面中没有给第二个矩形的坐标标号,那就仿照第一个矩形的坐标把输入的四个变量命名成
此时知道第一个矩形(小矩形)两条竖线的
if(x1_<=x1 && x2<=x2_ && y1_<=y1 && y2<=y2_) cout<<0,exit(0);
2. 第二个矩形能够完全包含第一个矩形的一条边
有如下四种可能。
其实这四种差不多,分析完第一种,就能同理得出剩下三种可能的判断方法和答案。
分析第一种,可以发现它要求第二个矩形的上下两边要夹住第一个矩形的上下两边,即
判断出现在两个矩形属于这种情况之后,还需要输出大布的最小面积。此时大布需要完全盖住露出来的那个绿色区域。这个区域左边那条边是第一个矩形左边那条边,即
剩下三个也可以同理推出:
- 当
x_1'\le x_1<x_2\le x_2',y_1<y_1'<y_2\le y_2' ,答案为(x_2-x_1)\times(y_1'-y_1) ; - 当
x_1'\le x_1<x_2'<x_2,y_1'\le y_1<y_2\le y_2' ,答案为(x_2-x_2')\times(y_2-y_1) ; - 当
x_1'\le x_1<x_2\le x_2',y_1'\le y_1<y_2'<y_2 ,答案为(x_2-x_1)\times(y_2-y_2') 。
if(x1<x1_ && x1_<x2 && x2<=x2_ && y1_<=y1 && y2<=y2_) cout<<(x1_-x1)*(y2-y1),exit(0);
if(x1_<=x1 && x2<=x2_ && y1<y1_ && y1_<y2 && y2<=y2_) cout<<(x2-x1)*(y1_-y1),exit(0);
if(x1_<=x1 && x1<x2_ && x2_<x2 && y1_<=y1 && y2<=y2_) cout<<(x2-x2_)*(y2-y1),exit(0);
if(x1_<=x1 && x2<=x2_ && y1_<=y1 && y1<y2_ && y2_<y2) cout<<(x2-x1)*(y2-y2_),exit(0);
3. 上面两种情况都不是
那就是刚开始讨论的第一种情况,答案是第一个矩形的面积,即
cout<<(x2-x1)*(y2-y1);
完整代码:
- 还有什么需要注意的?
- 由题面中“... are the coordinates of the lower-left and upper-right corners of the ...”可以看出,本题已经默认了
x_1<x_2 ,剩下的变量也一样。但是有的题目并没有给你排好序,需要注意一下。 y0,y1,yn,j0,j1,jn是cmath头文件的函数。如果要避免变量名冲突,可以给y1改个名字或者只#include<iostream>,而不#include<bits/stdc++.h>。
#include<iostream>
using namespace std;
int main(){
ios::sync_with_stdio(0);cin.tie(0);
int x1,y1,x2,y2,x1_,y1_,x2_,y2_;
cin>>x1>>y1>>x2>>y2>>x1_>>y1_>>x2_>>y2_;
if(x1_<=x1 && x2<=x2_ && y1_<=y1 && y2<=y2_)cout<<0,exit(0);
if(x1<x1_ && x1_<x2 && x2<=x2_ && y1_<=y1 && y2<=y2_)cout<<(x1_-x1)*(y2-y1),exit(0);
if(x1_<=x1 && x2<=x2_ && y1<y1_ && y1_<y2 && y2<=y2_)cout<<(x2-x1)*(y1_-y1),exit(0);
if(x1_<=x1 && x1<x2_ && x2_<x2 && y1_<=y1 && y2<=y2_)cout<<(x2-x2_)*(y2-y1),exit(0);
if(x1_<=x1 && x2<=x2_ && y1_<=y1 && y1<y2_ && y2_<y2)cout<<(x2-x1)*(y2-y2_),exit(0);
cout<<(x2-x1)*(y2-y1);
return 0;
}
相较于平方复杂度的暴力,这份