矩阵的并

Description

在 X-Y 坐标平面上,给定多个矩形,它们的边分别与坐标轴平行。请计算它们的并的面积。 

输入格式

输入第一行为一个整数 n,1<=n<=100,表示矩形的数量。
接下来有 n 行,每行包括四个数:x1,y1,x2,y2 (0<=x1<x2<=100000;0<=y1<y2<=100000),
用空格分开,不一定为整数。
(x1,y1)表示一个长方形的左下顶点坐标,(x2,y2)表示右上顶点坐标。 

输出格式

n个矩形的并的面积,保留两位小数

 


输入样例
2
0 0 2 2 
1 1 3 3 


输出样例
7.00

思路1:


原来的思路是有一些错误的,即我把每两个矩形的并面积算作 S = 两个矩形面积相加 - 两个矩形相交的面积,这思路乍一看没错,我提交时也这么想,但是WA了。问题就出在了如果三个矩形都有并的面积时
三个矩形相交的面积会被多减了一次导致错误,那么四个矩形相交、五个呢,这个bug有点难改,如果有神犇有思路还望指导一下,以下是我第一次的代码(WA的)
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn = 1e5+10;

struct Rec{
    double x1,y1;
    double x2,y2;
};

Rec rec[maxn];

int main(){
    int m;
    double sums = 0,subs = 0; 
    scanf("%d",&m);
    for(int i=0 ;i<m ;i++){
        scanf("%lf%lf%lf%lf",&rec[i].x1, &rec[i].y1, &rec[i].x2,&rec[i].y2);
        sums+= (rec[i].x2 - rec[i].x1)*(rec[i].y2 - rec[i].y1);
    }

    for(int i=0 ;i<m ;i++){ //去掉包含的
        for(int j=0 ;j<m ;j++){
            if(i == j)  continue;
            else if(rec[i].x1 >= rec[j].x1 && rec[i].x2 <= rec[j].x2)
                if(rec[i].y1 >= rec[j].y1 && rec[i].y2 <= rec[j].y2){
                    sums -= (rec[i].x2 - rec[i].x1)*(rec[i].y2 - rec[i].y1);
                    rec[i].x1 = rec[i].x2 =rec[i].y1 =rec[i].y2 = 0;
                }
        }
    }
    //double old = 0, subss;
    for(int i=0 ;i<m ;i++){  //以i为后面的和里面的矩形(被包围)
            //subss = subs;
        for(int j=0 ;j<m ;j++){
           // old = subs;
            if(i == j) continue;
            if(rec[i].x1 > rec[j].x1 && rec[i].x2 > rec[j].x2 && rec[j].x2 > rec[i].x1){ //相交
                if(rec[i].y2 > rec[j].y2 && rec[i].y1 > rec[j].y1 && rec[i].y1 < rec[j].y2) //右上
                    subs += (rec[j].x2- rec[i].x1)*(rec[j].y2 - rec[i].y1);
                else if(rec[i].y2 < rec[j].y2 &&rec[i].y1 > rec[j].y1) //右中
                    subs += (rec[j].x2 - rec[i].x1)*(rec[i].y2 - rec[i].y1);
                else if(rec[i].y2 < rec[j].y2 && rec[i].y2 > rec[j].y1 &&rec[i].y1 < rec[j].y1) //右下
                    subs += (rec[j].x2 - rec[i].x1)*(rec[i].y2 - rec[j].y1);
                else if(rec[i].y1 < rec[j].y1 && rec[i].y2 > rec[j].y2)
                    subs +=(rec[j].x2 - rec[i].x1)*(rec[j].y2 - rec[j].y1); //右包含
            }
            else if(rec[j].x1 <= rec[i].x1 && rec[i].x2 <= rec[j].x2){ //中包含
                int lenx = (rec[i].x2 - rec[i].x1);
                if(rec[i].y1 > rec[j].y1 && rec[i].y2 > rec[j].y2 && rec[i].y1 <rec[j].y2) //中上
                    subs += lenx*(rec[j].y2 - rec[i].y1);
                else if(rec[i].y1 < rec[j].y1 && rec[i].y2 < rec[j].y2 && rec[i].y2 > rec[j].y1) //下包含
                    subs +=(rec[i].y2 - rec[j].y1)*lenx;
                else if(rec[i].y1 < rec[j].y1 && rec[i].y2 > rec[j].y2) //贯穿
                    subs += (rec[j].y2 - rec[j].y1)*lenx;
            }
            //printf("%d %d %.2lf \n",i,j,subs - old);
        }
        //printf("*********%.2lf\n",subs - subss);
    }
    printf("%.2lf\n",sums - subs);
}
 

思路2:

后面这个思路是我看了大佬的代码才想出来的,主要思路是枚举在合并后矩形的各个横、纵坐标,再把横纵坐标组成的矩形面积相加,及矩阵的并面积(这里我觉得我说的不太清楚,具体看代码吧)
#include<stdio.h>
#include<stdlib.h>
#include<algorithm>
#include<iostream>
using namespace std;
struct rectangle{    //结构体,保存矩形
       float x1;
       float y1;
       float x2;
       float y2; 
};
       
rectangle arr[101];    
float x[200];
float y[200];
int flag[200][200]; 
       
int main(){
   
   float count=0;
   int n;
   int k=0;
   scanf("%d",&n);                             //数据输入
    for(int i=0;i<n;i++){         
            scanf("%f",&arr[i].x1);
            scanf("%f",&arr[i].y1);
            scanf("%f",&arr[i].x2);
            scanf("%f",&arr[i].y2);
            x[k]=arr[i].x1;                   //保存所有X坐标到X[]数组,Y 到Y[]数组
            y[k]=arr[i].y1;
            k++;
            x[k]=arr[i].x2;
            y[k]=arr[i].y2;
            k++;
            }
    sort(x,x+k);        //分别排序     
    sort(y,y+k);for(int h=0;h<n;h++)          //循环查找在矩形内的小矩形
       for(int i=0;i<2*n;i++){
          if(x[i]>=arr[h].x2)
              break;     
          for(int j=0;j<2*n;j++){
             if(y[j]>=arr[h].y2)
                break;
             if(x[i]>=arr[h].x1&&y[j]>=arr[h].y1)
                flag[i][j]=1;                       //符合,标志
          }
       }
                                   
      
    for(int i=0;i<2*n;i++)               //统计面积
       for(int j=0;j<2*n;j++)
          count+=flag[i][j]*(x[i+1]-x[i])*(y[j+1]-y[j]);     
             
    printf("%.2f",count);
   return 0;
}

 

 
posted @ 2020-11-08 20:50  Jesen等不等式  阅读(538)  评论(0编辑  收藏  举报