田地丈量 | |
时间限制: | 1.0s |
内存限制: | 512.0MB |
问题描述: | 问题描述西西艾弗岛上散落着 n 块田地。每块田地可视为平面直角坐标系下的一块矩形区域,由左下角坐标 (x1,y1) 和右上角坐标 (x2,y2) 唯一确定,且满足 x1<x2、y1<y2。这 n 块田地中,任意两块的交集面积均为 0,仅边界处可能有所重叠。 最近,顿顿想要在南山脚下开垦出一块面积为 a×b 矩形田地,其左下角坐标为 (0,0)、右上角坐标为 (a,b)。试计算顿顿选定区域内已经存在的田地面积。 输入格式从标准输入读入数据。 输入共 n+1 行。 输入的第一行包含空格分隔的三个正整数 n、a 和 b,分别表示西西艾弗岛上田地块数和顿顿选定区域的右上角坐标。 接下来 n 行,每行包含空格分隔的四个整数 x1、y1、x2 和 y2,表示一块田地的位置。 输出格式输出到标准输出。 输出一个整数,表示顿顿选定区域内的田地面积。 样例输入 样例输出 样例解释如图所示,选定区域内田地(绿色区域)面积为 44。 子任务全部的测试数据满足 n≤100,且所有输入坐标的绝对值均不超过 104。 |
题解
题目是第一道题,不应该要运用很复杂的算法,因此要善于总结规律
我们不妨把x坐标和y坐标分开来看
以x坐标为例,如图:
设矩形1的上下左右边界在坐标轴上的投影为up,bottom,left,right,黄色竖线为矩形1的左右边界,交集部分在横坐标上的跨度就是红色线。
容易看出交集的右边界为min(Rect1-R,a),左边界为max(Rect1-L,0).在纵坐标上同样如此:上边界为min(b,Rect1-UP),下边界为max(0,Rect1-Bottom).
因此,我们可以得出
如果Width<0或Height<0,就不存在交集。具体代码如下:
AC code
#include<cstdio>
int ans=0;
int min(int a,int b){
return a>b?b:a;
}
int max(int a,int b){
return a>b?a:b;
}
int main(){
int n,a,b;
int x1,y1,x2,y2;
scanf("%d%d%d",&n,&a,&b);
for(int i=1;i<=n;i++){
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
int kuan=min(a,x2)-max(0,x1);
int gao=min(b,y2)-max(0,y1);
if(kuan>0 && gao>0){
ans+=kuan*gao;
}
}
printf("%d",ans);
return 0;
}
扩展 :
上面的内容其实就是各矩形与左下顶点为(0,0),右上顶点为(a,b)的矩形的交集
更一般的,如果要求两个矩形的交集的面积,只需将这个矩形的坐标修改即可,具体代码如下:
Code
#include<cstdio>
int min(int a,int b){
return a>b?b:a;
}
int max(int a,int b){
return a>b?a:b;
}
int main(){
int x1,y1,x2,y2;
int _x1,_x2,_y1,_y2;
while(1){
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
scanf("%d%d%d%d",&_x1,&_y1,&_x2,&_y2);
int kuan=min(_x2,x2)-max(_x1,x1);
int gao=min(_y2,y2)-max(_y1,y1);
if(kuan>0 && gao>0){
printf("%d\n",kuan*gao);
}
}
return 0;
}
制作不易,感谢支持!交流请联系QQ:2757840732
今天是10月24日程序员节,祝愿各位程序员编译成功,0错误,0警告,0调试!