zoukankan      html  css  js  c++  java
  • 矩阵的并

    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 
    ",i,j,subs - old);
            }
            //printf("*********%.2lf
    ",subs - subss);
        }
        printf("%.2lf
    ",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;
    }
    
    
    
     
  • 相关阅读:
    js总结:增加和减少文本框
    java总结:字符串切割
    Spring-----ioc
    Hibernate之二级缓存
    Hibernate之HQL
    Hibernate关联关系(一对多自关联 ,多对多)
    Hibernate关联关系(一对多)
    Hibernate之主键生成策略
    如何使用hibernate完成CRUD操作
    Struts2-----文件上传与拦截器原理
  • 原文地址:https://www.cnblogs.com/wxx23-IOU/p/13944615.html
Copyright © 2011-2022 走看看