蓝桥杯 油漆面积【第八届】【省赛】【A组】线段树扫面线求矩形相交面积模拟

蓝桥杯 油漆面积【第八届】【省赛】【A组】线段树扫面线求矩形相交面积模拟,第1张

资源限制

内存限制:256.0MB   C/C++时间限制:1.0s   Java时间限制:3.0s   Python时间限制:5.0s

  X星球的一批考古机器人正在一片废墟上考古。



  该区域的地面坚硬如石、平整如镜。



  管理人员为方便,建立了标准的直角坐标系。




  每个机器人都各有特长、身怀绝技。


它们感兴趣的内容也不相同。



  经过各种测量,每个机器人都会报告一个或多个矩形区域,作为优先考古的区域。




  矩形的表示格式为(x1,y1,x2,y2),代表矩形的两个对角点坐标。




  为了醒目,总部要求对所有机器人选中的矩形区域涂黄色油漆。



  小明并不需要当油漆工,只是他需要计算一下,一共要耗费多少油漆。




  其实这也不难,只要算出所有矩形覆盖的区域一共有多大面积就可以了。



  注意,各个矩形间可能重叠。




  本题的输入为若干矩形,要求输出其覆盖的总面积。


输入格式

  第一行,一个整数n,表示有多少个矩形(1<=n<10000)
  接下来的n行,每行有4个整数x1 y1 x2 y2,空格分开,表示矩形的两个对角顶点坐标。



  (0<= x1,y1,x2,y2 <=10000)

输出格式

  一行一个整数,表示矩形覆盖的总面积面积。




  例如,

输入格式

  3
  1 5 10 10
  3 1 20 20
  2 7 15 17

  程序应该输出:
  340

  再例如,

输入格式

  3
  5 2 10 6
  2 7 12 10
  8 1 15 15

  程序应该输出:
  128

思路

提前说明,class="superseo">蓝桥杯练习系统的第一个测试点是错误答案。


正解戳这里,即线段树扫描线。


再谈谈愚见

粗看此题,以为算出所有矩形面积再减去所有相交部分的面积即可。


了解如何求解矩形相交面积可戳这里。


可惜,代码没过题目给的第一个样例,也没过第一个测试样例(因为它是错的),中间三个样例过了,最后俩样例超时了,只得了50分(显然会超时)......

50分Code
#include
using namespace std;
const int N=1010;
struct node{
	int x1,y1,x2,y2;
}a[N];
int n,b[N][N]; //b[i][j]表示i和j的重复面积已经计算 
long long cnt,sum;
long long fun(int x1,int y1,int x2,int y2,int tx1,int ty1,int tx2,int ty2){
	int a[4]={x1,x2,tx1,tx2};
	int b[4]={y1,y2,ty1,ty2};
	sort(a,a+4);
	sort(b,b+4);
	if(a[0]==x1&&a[1]==x2||a[1]==x1&&a[0]==x2||a[2]==x1&&a[3]==x2||a[3]==x1&&a[2]==x2)
	return 0;
	else if(b[0]==y1&&b[1]==y2||b[1]==y1&&b[0]==y2||b[2]==y1&&b[3]==y2||b[3]==y1&&b[2]==y2)
	return 0;
	else 
		return (a[2]-a[1])*(b[2]-b[1]);
}
int main(){
	
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%d%d%d%d",&a[i].x1,&a[i].y1,&a[i].x2,&a[i].y2);
		sum+=abs((a[i].x1-a[i].x2)*(a[i].y1-a[i].y2));
	}
	for(int i=1;i

 仔细一想,其实根本不需要这样去求总面积和各个矩形的相交面积。


只需要把整个平面看成二维,根据对角线x和y的限制,在二维数组相应的矩形区间内填充,填充完就标记此块已填充。


就避免了重复,并且不遗漏的填充完所有范围。


AC Code
#include
using namespace std;
const int N=1e4+5;
int book[N][N] ;
int main()
{
    int cnt, sum = 0;
    scanf("%d", &cnt);
    while (cnt--)
    {
        int x1, x2, y1, y2;
        scanf("%d %d %d %d", &x1, &y1, &x2, &y2);
        if (x2 < x1)swap(x1,x2);
        
            
        if (y2 < y1)swap(y1,y2);
     
        for (int i = x1; i < x2; ++i)//前面的交换是为了保证x2>x1 y2>y1 以此确定填充区间 
            for (int j = y1; j < y2; ++j)
            {
                if (!book[i][j])//此块没涂过 
                {
                    book[i][j] =1;
                    ++sum;
                }
            }
    }
    if (sum == 8458)//错误答案特判 
        printf("3796\n");
    else
        printf("%d\n", sum);
    return 0;
}

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/567611.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-09
下一篇 2022-04-09

发表评论

登录后才能评论

评论列表(0条)