我正在尝试解决代码预算的“ RECTMEET”问题。我写了这段代码:
int main(void) {
int x11, x12, x21, x22, y11, y12, y21, y22, a1, a2, a3;
scanf("%d", &x11);
scanf("%d", &y11);
scanf("%d", &x12);
scanf("%d", &y12);
scanf("%d", &x21);
scanf("%d", &y21);
scanf("%d", &x22);
scanf("%d", &y22);
a1 = (x12 - x11) * (y12 - y11);
a2 = (x22 - x21) * (y22 - y21);
if (x21 >= x11 && x21 <= x12 && y21 >= y11 && y21 <= y12) {
a3 = (x12 - x21) * (y12 - y21);
} else
if (x22 >= x11 && x22 <= x12 && y22 >= y11 && y22 <= y12) {
a3 = (x22 - x11) * (y22 - y11);
} else {
a3 = 0;
}
printf("%d", a1 + a2 - a3);
return 0;
}
我尝试了许多案例,但所有案例都得到了正确答案,但是提交此解决方案时,我得到了错误答案。我在这里做错了什么?
答案 0 :(得分:1)
可以使用扫掠线算法解决此类问题。但是根据您的代码,让我们再考虑一下。两个矩形的并集面积首先是两个矩形的和,然后从和中减去相交面积。那么,如何计算相交面积?
在以下四种情况下,不可能有交叉区域。
A2完全位于A1的右侧(即if(x21> = x12)
A2完全位于A1的左侧(即if(x22 <= x11)
A2完全位于A1的顶部(即if(y21> = y12)
A2完全位于A1的底部(即if(y22 <= y11)
现在是时候考虑相交的情况了。
A1的宽度= WA1 = x12-x11
A2的宽度= WA2 = x22-x21
==>交叉区域的宽度,W =(WA1 + WA2-(左侧diff)-(右侧diff))/ 2
即W =((x12-x11)+(x22-x21)-abs(x21-x11)-abs(x22-x12))/ 2
和交点区域的高度H =(HA1 + HA2-(顶手侧diff)-(底手侧diff))/ 2
即H =((y12-y11)+(y22-y21)-abs(y21-y11)-abs(y22-y12))/ 2
则交叉区域为W * H
#include <stdio.h>
#include <stdlib.h>
int main(void) {
// your code goes here
int x11, x12, x21, x22, y11, y12, y21, y22, a1, a2, a3;
scanf("%d", &x11);
scanf("%d", &y11);
scanf("%d", &x12);
scanf("%d", &y12);
scanf("%d", &x21);
scanf("%d", &y21);
scanf("%d", &x22);
scanf("%d", &y22);
a1 = (x12 - x11) * (y12 - y11);
a2 = (x22 - x21) * (y22 - y21);
if (x21 >= x12 || x22 <= x11 || y21 >= y12 || y22 <= y11) {
a3 = 0;
} else {
a3 = (x12 - x11 + x22 - x21 - abs(x21 - x11) - abs(x22 - x12)) / 2 *
(y12 - y11 + y22 - y21 - abs(y21 - y11) - abs(y22 - y12)) / 2;
}
printf("%d", a1 + a2 - a3);
return 0;
}
答案 1 :(得分:1)
分别考虑x和y。每种情况分为以下6种情况。
单独对待它们很麻烦。我更喜欢以统一的方式计算重叠面积。
x31 = max(x11, x21)
x32 = min(x12, x22)
y31 = max(y11, y21)
y32 = min(y12, y22)
a3 = max(0, x32 - x31) * max(0, y32 - y31)