【赛氪 Saikr】不正方形(数学、平面几何 ps:今天打了假赛)

题目:

不正方形

Description

今天是数学课!小A发现同学们上课很消极,于是给大家出了一个数学小游戏。

小A在黑板上画了一个很大很大的平面直角坐标系,然后给出了若干个红点和黄点,现在同学们需要回答,这些点能否构成一个不正方形

不正方形的定义为:四个点构成一个凸四边形,且相对顶点颜色相同,相邻顶点颜色不同。

为了降低难度,认真的小A保证不会有重点(即不会有两个点坐标相同),也不会有三个点共线的情况。

同学们觉得很有趣,但这个问题对于小朋友们还太难了,聪明的你能帮帮他们吗?

Input

第一行两个正整数,n、m。

接下来n行,每行两个整数x和y,表示红点的坐标。

接下来m行,每行两个整数x和y,表示黄点的坐标。

1<n,m<=250, 1<=x,y<=10 7

Output

如果能构成,输出“YES”;否则,输出“NO”。(不含双引号)

Sample Input 1

2 2
1 1
2 2
1 2
2 1

Sample Output 1

YES

解题思路:

这题感觉是一个数学题,关键就在这个凸四边形。什么是凸四边形简单来说就是四边形的内角全部都小于180度,理解到这对于解这个题已经足够了,首先我们需要知道怎么样才能画出凸四边形,我们假想在一个二维平面中选择三个点,我们会发现在第四个点确定之前我们是没有办法得知这个四边形是凹四边形还是凸四边形,所以第四个点的位置将决定该四边形的形状,我们找到凹凸转换的临界态时第四个点的位置就能解出来这道题了,当第四个点在已经确定出的对角线上时,以第四个点为顶点的内角为180度。在这条对角线上开始,只增大或者减小横坐标都可能使四边形变成凸多边形,具体增大或者减小与另一个点的位置有关,移动完后,如果这两个点位于对角线的同一侧,那么就是凹多边形,异侧就是凸多边形

接下来就是用程序语言解决问题了,题目还有一个要求,相邻点颜色不同,对角点颜色相同,别看这个是一个附加条件实际上是为我们解题提供便利,这在告诉我们如何找对角线的点,依次取一种颜色中的两个点,判断其他颜色点相对于这两点构成直线的位置,如果在两侧都有另一种颜色的点那么就可以画出凸正方形,如果没有那么就不可以。

代码部分:

#include<bits/stdc++.h>
using namespace std;
int red[255][2],yellow[255][2];//红色、黄色两点的位置;

bool check_up(int a,int b,int c,int d,int e,int f)//判断点(e,f)是否在(a,b),(c,d)所构成的直线(一条对角线)上方;
{
    double k = (double)(b-d)/(a-c);
    double b_ = (double)b-(double)a*k;
    double y_ = (double)e*k+b_;
    double f_ = (double)f;
    if(f_ >= y_)
    return true;
    else
        return false;

}
int main()
{
    int n,m;
    cin >> n >> m;
   //两种颜色的输入
    for(int i = 0; i < n; i++)
    {
        int a,b;
        cin >> a >> b;
        red[i][0] = a;
        red[i][1] = b;
    }
    for(int i = 0; i < n; i++)
    {
        int a,b;
        cin >> a >> b;
        yellow[i][0] = a;
        yellow[i][1] = b;
    }
    int up,low;
    //遍历任选红色点的所有可能;
    for(int i = 0; i < n; i++)
    {
        for(int j = i; j < n; j++)
        {
             up = 0,low = 0;//上方是否有点和下方是否有点的标记;
             for(int k = 0; k < m; k++)
             {
                 if(check_up(red[i][0],red[i][1],red[j][0],red[j][1],yellow[k][0],yellow[k][1]))
                    up = 1;
                 else
                    low = 1;
             }
             if(up == 1 && low == 1)//可以画出凸四边形;
                break;
        }
        if(up == 1 && low == 1)
                break;
    }
    if(up == 1 && low == 1)//可以画出凸四边形;
        cout << "YES" ;
    else
        cout << "NO";
    return 0;
}

PS:前几天在赛氪上买了一个比赛,今天是比赛时间,这道题也是我今天做的,但是并不是比赛题目........ma die我进错oj了,因为开始的时候晚了一点,所以开始看到题啥都没想就开始做了,比赛结束,我随便点着看,结果发现了正确的竞赛入口,额......绝望,打了个真“假赛”,还好不是啥大比赛,就当花钱买了个教训以后细致一点吧,也提醒大家不要犯和我一样愚蠢的错误。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值