田地丈量(CSP202303-1)巧妙解法

田地丈量
时间限制: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,表示一块田地的位置。

输出格式

输出到标准输出。

输出一个整数,表示顿顿选定区域内的田地面积。

样例输入

4 10 10
0 0 5 5
5 -2 15 3
8 8 15 15
-2 10 3 15

样例输出

44

样例解释

如图所示,选定区域内田地(绿色区域)面积为 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=min(a,right)-max(0,left)

                                        Height=min(b,up)-max(0,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调试!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值