一道算法题-求三个矩形的交集矩形。

给定矩形的定义如下:

struct Rect{
    int x; //表示矩形的左上水平坐标
    int y; //表示矩形的左上垂直坐标
    int w; //表示矩形宽度
    int h; //表示矩形高度
};

现在给三个矩形,求三个矩形的交集,如果没有交集,那么矩形的x,y,w和h均赋值为-1。例如下面示例图,求出三个矩形相交的粗线线框表示的矩形。

解题思路: 
解题思路很重要,没有集体思路,题目肯定是做出不来的。下面给出本人的解题思路: 
(1)判断三个矩形有没有交集。这个是难点,该怎么做呢?可以在x轴方向将三个矩形按x的大小从左到右排列,判断两两矩形在x轴方向是否有交集,如果有任意一对没有相交那么三个矩形没有交集。判断方法是如果rectB.x>=rectA.x+rectA.w的话,那么说明rectA和rectB之间没有交集。

同理,在y轴方向做同样的判断;

(2)求出任意两个矩形的交集矩形,再将交集矩形与第三个矩形再求交集,可得最后的交集矩形。

有了正确和清晰的思路,就可以写代码了,下面给出本人的实现,可供网友参考。

 1 #include <iostream>
 2 using namespace std;
 3 #include <vector>
 4 #include <algorithm>
 5
 6 struct Rect{
 7     int x; //表示矩形的左上水平坐标
 8     int y; //表示矩形的左上垂直坐标
 9     int w; //表示矩形宽度
10     int h; //表示矩形高度
11 };
12
13 //按照x递增排序
14 bool compareX(const Rect& rectA,const Rect& rectB ){
15     return rectA.x<rectB.x;
16 }
17
18 //按照y递增排序
19 bool compareY(const Rect& rectA,const Rect& rectB ){
20     return rectA.y<rectB.y;
21 }
22
23 //判断三个矩形是否相交
24 bool isIntersect(const Rect& rectA,const Rect& rectB,const Rect& rectC){
25     Rect rectLeft,rectXMid,rectRight; //从左向右的矩形
26     Rect rectTop,rectYMid,rectBelow;  //从上到下的矩形
27
28     //将矩形按照x由左向右排序
29     vector<const Rect> vec;
30     vec.push_back(rectA);
31     vec.push_back(rectB);
32     vec.push_back(rectC);
33     sort(vec.begin(),vec.end(),compareX);
34     rectLeft=vec[0],rectXMid=vec[1],rectRight=vec[2];
35
36     //水平方向任意两个矩形没有交集
37     if(rectXMid.x>=rectLeft.x+rectLeft.w||rectRight.x>=rectXMid.x+rectXMid.w||rectRight.x>=rectLeft.x+rectLeft.w)
38         return false;
39
40     //同理将矩形按照y由上往下排序
41     sort(vec.begin(),vec.end(),compareY);
42     rectTop=vec[0],rectYMid=vec[1],rectBelow=vec[2];
43
44     //垂直方向任意两个矩形没有交集
45     if(rectYMid.y>=rectTop.y+rectTop.h||rectBelow.y>=rectYMid.y+rectYMid.h||rectBelow.y>=rectTop.y+rectTop.h)
46         return false;
47     return true; //三个矩形有交集
48 }
49
50 //两个矩形的交集,前提是两个矩形一定有交集
51 Rect intersection(const Rect& rectA,const Rect& rectB){
52     Rect resRect;
53     resRect.x=rectA.x>rectB.x?rectA.x:rectB.x; //选最右边的矩形的x作为交集的x
54     resRect.y=rectA.y>rectB.y?rectA.y:rectB.y; //选最下面的矩形的y作为交集的y
55     //选择左边矩形(x坐标较小者)的右边的作为交集矩形的右边,这样就可以求出交集矩形的宽度
56     resRect.w=rectA.x+rectA.w<rectB.x+rectB.w?rectA.x+rectA.w-resRect.x:rectB.x+rectB.w-resRect.x;
57     //同理,选择上面矩形(y坐标较小者)的下边的作为交集矩形的下边,这样就可以求出交集矩形的高度
58     resRect.h=rectA.y+rectA.h<rectB.y+rectB.y?rectA.y+rectA.h-resRect.y:rectB.y+rectB.h-resRect.y;
59     return resRect;
60 }
61
62
63 //求三个矩形的交集
64 Rect threeIntersection(const Rect& rectA,const Rect& rectB,const Rect& rectC){
65     Rect res;
66     bool isIntersectBool=isIntersect(rectA,rectB,rectC);
67     if(isIntersectBool){ //有相交
68         Rect rectAB=intersection(rectA,rectB);
69         res=intersection(rectAB,rectC);
70     }
71     else
72         res.x=res.y=res.w=res.h=-1;
73     return res;
74 }

测试结果如下:

int main(){
    Rect rectA,rectB,rectC;
    //测试案例1
    //rectA.x=0,rectA.y=0,rectA.w=1,rectA.h=1;
    //rectB.x=1,rectB.y=1,rectB.w=1,rectB.h=1;
    //rectC.x=2,rectC.y=2,rectC.w=1,rectC.h=1;

    //测试案例2
    rectA.x=0,rectA.y=0,rectA.w=2,rectA.h=2;
    rectB.x=1,rectB.y=1,rectB.w=1,rectB.h=1;
    rectC.x=1,rectC.y=1,rectC.w=1,rectC.h=1;

    Rect resRect=threeIntersection(rectA,rectB,rectC);
    if(resRect.x!=-1){ //有相交
        cout<<"resRect.x:"<<resRect.x<<endl;
        cout<<"resRect.y:"<<resRect.x<<endl;
        cout<<"resRect.w:"<<resRect.x<<endl;
        cout<<"resRect.h:"<<resRect.x<<endl;
    }
    else
        cout<<"not intersect"<<endl;
    getchar();
}

测试案例1输出:not intersect; 
测试案例2输出: 
resRect.x:1 
resRect.y:1 
resRect.w:1 
resRect.h:1

原文地址:https://www.cnblogs.com/smile233/p/8331679.html

时间: 2024-07-31 03:33:43

一道算法题-求三个矩形的交集矩形。的相关文章

一天一道算法题---6.8--数学题

感谢微信平台:一天一道算法题---每天多一点进步----明天 考离散了 明天 高考结束了 看上去都是 好日子..... 上题目了: 求出用1 , 2 ,5这三个数不同个数的组合的和为100的组合个数. 如:100个1是一个组合:5个1+19个5是一个组合 OK:--- 几天折磨后 终于来了个 我能做的.... PS:  关于6.7--栈中O(1)实现min函数等的  应该会在今晚贴上.. 平台上关于这题的分析很到位: 设 1的个数为X 2的个数为Y 5的个数为Z 和为100的组合总数为cnt 1

一天一道算法题--6.5--数学题

感谢 微信平台: 一天一道算法题 ---每天多一点进步---- 话说 这题 我百度了一下 没找到哪个OJ 有出这题 下次 来给我们的学弟学妹们把.... 那我来说下题目大意: 给你一个n 问你从1,2,3--n中选出3个数 能够构成多少种不同的三角形 比如N=5 可以有(2,3,4)(2,3,5)(3,4,5)三种 输入:(3<=n<=n1000000) 输出:种类数 首先 既然是做acm 那么 一般暴力 都直接放弃吧 这里也需要O(n^3)  GG 这里 微信提供的分析 很好  我相信 你慢

前端面试的一道算法题

(使用canvas解答) 下面说一个跟前端有点相关并且有点趣的一道算法题. 题目: 平面上有若干个不特定的形状,如下图所示.请写程序求出物体的个数,以及每个不同物体的面积. 分析 想要知道有多少个图形,想到的就是先获取图片中的每一个像素点然后判获取像素点的背景颜色(RGBA).想要获得图片中的每一个像素点,那就可以联想到使用h5的canvas.如下: 菜鸟教程中canvas的getimagedata方法http://www.runoob.com/tags/canvas-getimagedata.

一天一道算法题---5.26---思维锻炼

感谢 微信平台: 一天一道算法题 -----  大家没事都可以去关注他 --- 不是做广告的---- 题目大意:  给你一个长度为n的整数序列A1,A2,--,An,找出两个整数Ai和Aj(i<j),使得Ai-Aj尽量大 反正 暴力肯定超时..... 数据大小 我也就给出了 反正 尽量用最好算法去解 就是了 嗯 它给的是o(n)的时间复杂度和空间度   但是很容易转换成o(1)空间度 o(n)时间复杂度的写法 这边给出个 与这题意相同的一个 题目  发现竟然是我以前WA的 怪不得 那么熟悉 ..

算法——一天一道算法题篇——找只出现一次的两个数

找只出现一次的两个数 题目: 一个整型数组里除了两个数字只出现一次之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字. 举例说明: 现在有一个数组:{1,3,4,2,4,3}; 假设数组元素的规模不是很大,想要找到只出现一次的元素,可以定义一个辅助数组,flag[100];里面存放的是数组元素出现的次数,flag数组的下标表示的是数组:{1,3,4,2,4,3}里的元素. 代码如下: package hello.ant; public class AlogArrayFind2 {

一天一道算法题---6.11---大数阶乘

感谢微信平台----一天一道算法题----每天多一点进步 大数的概念 感觉是我接触acm 1 2 个月之后才有的....64位的Long long 和 __int64 也大概都是那时候才有的.. 大数 相加 相乘 相除 求余  相减不知道 有没有... 都是应该要掌握的.. 可能 我也会陆续把上面的全慢慢贴上来 // 呆会就直接把 微信提供的代码给贴上来了  先要去次午饭了 早饭 午饭永远是连一起的 .......... // 刚刚碰到个最小生成树的题 第一次用了邻接表去做 蛮cool == 一

一天一道算法题---6.3---二分运用

感谢微信平台 : 一天一道算法题 -----  一天多一点进步----- 先来段 废话: 已经 3 4天没更了 主要还是自己 太懒了 .... 好 让我们 开始吧 题目链接: touch  me 是不是 有点长啊  最可恶的是 还有张 诱人的 馅饼  --- 话说 有个很好的美国系列校园青春 sex movie ---  American Pie  --- 美国派----- 题目大意: 有F+1个人来分N个圆形蛋糕 每个人得到的必是一整块蛋糕 (不是由几块拼在一起的)面积要相同 求每个人最多能得

C++笔试面试(算法题集三)

1>    编写strcpy函数,已知函数原型char*strcpy(char* strDest,char* strSrc) ANSWER: Chat* strcpy(char* strDest,char* strSrc) { If(strSrc==NULL)  return NULL; Char*ch1=strSrc,*ch2=strDest; While(*ch1!='\0') { *ch2++=*ch1++; } *ch2='\0'; Return strDest; } 2>    用递

一天一道算法题---6.26---二分查找

感谢微信平台---一天一道算法题----每天多一点进步-- 好累啊  现在在用win7自带的输入法 打起来真麻烦 快点把这2天的搞完就重装了 还是直接来源于----〉 待字闺中 分析 给定一个数组A,其中有一个位置被称为Magic Index,含义是:如果i是Magic Index,则A[i] = i.假设A中的元素递增有序.且不重复,请给出方法,找到这个Magic Index.更进一步,当A中允许有重复的元素,该怎么办呢? 没有重复元素的情况 一些同学在遇到这个题目的时候,往往会觉得比较简单.