假期刷题打卡--Day22

文章介绍了如何通过输入两个矩形的四个顶点坐标,使用C++代码判断两个矩形是否相交,重点在于处理相切和重合两种特殊情况。作者先排除重合和仅相切的情况,然后根据矩形的位置关系确定是否相交。
摘要由CSDN通过智能技术生成

1、MT1184矩形相交

输入2个矩形的左上角和右下角两个点的坐标值(x,y),判断2个矩形是否相交,输出YES或者NO。矩形的边应与x,y轴相平行。假定输入坐标能顺利构成矩形,不考虑无效矩形的情况。

格式

输入格式:

输入整型,空格分隔。 每行输入一组信息。

输出格式:

输出YES或者NO

样例 1

输入:

-20 20 20 -10 
-10 10 10 -5

输出:

NO

复制

备注

特殊情况考虑:在数学中,两个图形相交是指它们有公共的部分,或者说同时属于两者的点的集合不是空集。若两个几何图形在某个地方有且只有一个交点,则可以称为相切而不是相交。即,在此题中,两矩形只有一交点视为相切,有一条边完全或者部分重合视为相交。两矩形完全重合,视为重合不是相交。

分析过程

根据本题备注,可知,有几个特殊的情况不被认为是相交:

  1. 有且只有一个交点,则可以称为相切而不是相交;
  2. 两矩形完全重合,视为重合不是相交;
  3. 两矩形完全没有交点,即为不相交。

        根据备注的“两个图形相交是指它们有公共的部分”这句话,我们可知,图形相交的情况太多了,考虑图形不相交的情况反倒显得简单一点,所以在本题中,我们考虑不相交的情形,排除这些情形,剩下的就是相交的了。

按照上面的三种情形,我写了以下代码:

#include<bits/stdc++.h> 

using namespace std;

int main( )
{
    int x1,y1,x2,y2,x3,y3,x4,y4;
    scanf("%d %d %d %d\n",&x1,&y1,&x2,&y2);
    scanf("%d %d %d %d",&x3,&y3,&x4,&y4);
//首先判断重合这个情况,即两个矩形的左上角和右下角相同
    if(x1==x3&&y1==y3&&x2==x4&&y2==y4){
        cout << "NO";
        return 0;
    }
//相切的情况,即仅相交于一点    
    else if((x1==x4&&y1==y4)||(x2==x3&&y2==y3)){
        cout << "NO";
        return 0;
    }
//包含的情况
    else if( (x1<x3&&x4<x2&&y4>y2&&y1>y3  ) ||(x3<x1&&x2<x4&&y2>y4&&y3>y1)){
        cout << "NO";
        return 0;        
    }
//两个矩形的相对位置 左右上下
     else if(x1>x4||x2<x3||y1<y4||y2>y3)//随便写,只要满足相对位置就可
    { 
        cout << "NO";
        return 0;     
    }
    else
        cout << "YES";   
    return 0;
}

但是,本代码无法通过所有的用例。 

这是由于,我只考虑到了题目中说到的左上角和右下角,而没有顾及到左下角和右上角。在相切这个情况下,可以相交的是左下角和右上角,即下面这两种情况:

(参考来源:MT1184矩形相交 题解【超详细】 - CodeAntenna真的很详细!!!大家可以参考参考。(下面图我直接参考使用了,若是侵权,请联系我删除,谢谢啦~)
 

 

但是,我想不到该如何表示这两种情况,所以,根据这个博主的思路(还是有点不太理解,呜呜呜呜~),我修改了相关的代码, 然后就全部通过了,他(她)真的太厉害了,非常建议大家去看看。

因为我刚开始看了上面这两种情况,我没太理解,所以我就去看了一下轩哥码题:【码蹄集新手村全题解09】选择结构 MT1168 – MT1184_哔哩哔哩_bilibili

我只跳看了他画图的那一点视频,虽然我没看完(后来我理解了之后想去看看是不是这个意思,看完了,发现他好像没讲这些,所以我就直接这么理解了),但是看到他亲手花了四个图,我突然就理解了(y1==y4&&x2==x3) || (y3==y2&&x4==x1)这两个语句这么写的意义, 这两个语句是相对于x轴和y轴的,而不是说题目中所给的条件是非要在一个点上才能表示相等。

比如说(y1==y4&&x2==x3)这个语句:y1==y4,就表示它们(y1,y4)在平行于x轴的一条直线上,x2==x3则表示,它们(x2,x3)在平行于y轴的一条直线上。这么大白话可能还是不好理解,结合上面左边的这个图一起理解,就很好理解了。

实现代码
#include<bits/stdc++.h> 

using namespace std;

int main( )
{
    int x1,y1,x2,y2,x3,y3,x4,y4;
    scanf("%d %d %d %d\n",&x1,&y1,&x2,&y2);
    scanf("%d %d %d %d",&x3,&y3,&x4,&y4);
//首先判断重合这个情况,即两个矩形的左上角和右下角相同
    if(x1==x3&&y1==y3&&x2==x4&&y2==y4){
        cout << "NO";
        return 0;
    }
//相切的情况,即仅相交于一点    
    else if((x1==x4&&y1==y4)|| (y1==y4&&x2==x3) || (y3==y2&&x4==x1)||(x2==x3&&y2==y3)){
        cout << "NO";
        return 0;
    }
//包含的情况
    else if( (x1<x3&&x4<x2&&y4>y2&&y1>y3  ) ||(x3<x1&&x2<x4&&y2>y4&&y3>y1)){
        cout << "NO";
        return 0;        
    }
//两个矩形的相对位置 左右上下
     else if(x1>x4||x2<x3||y1<y4||y2>y3)//随便写,只要满足相对位置就可
    { 
        cout << "NO";
        return 0;     
    }
    else
        cout << "YES";   
    return 0;
}

OK,选择结构所有题目解决(除了VIP题,若是非会员想看看可以直接去看看轩哥码题,里面都有讲解,我后面可能去看看),我们一起开始下面模块吧~

循环结构暂时没有遇到需要注意的知识点。

明天继续吧。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值