poj 1410

题目概述

给定线段的端点坐标(x1,y1),(x2,y2),矩形一条对角线上的两个点(x3,y3),(x5,y5),定义矩形的边及内部均属于矩形,相交为线段和矩形有至少一个公共点,且矩形四条边必然分别平行于两条坐标轴,问线段和矩形是否相交

时限

1000ms/3000ms

输入

第一行正整数times,其后times行,每行8个整数x1,y1,x2,y2,x3,y3,x5,y5

限制

没有限制

输出

每行一个字符,若相交,输出T,否则F

样例输入

3
4 9 11 2 1 5 7 1
4 8 11 1 1 5 7 1
4 5 6 5 10 0 0 10

样例输出

F
T
T

讨论

计算几何,矩形与线段位置关系,不过题目描述略坑,其一是矩形内部也算矩形,额直接思维定势贡献一个WA,其二是原题中给出的是矩形左上和右下点,但后来又说左上和右下和相对位置没有什么关系,换言之,只是随便给了一条对角线上两个点,不过这个对额没有产生任何影响,其他的部分,由于矩形四条边一定平行与坐标轴,因此直接对矩形和线段做快速排斥就能判断是否在内部,但若矩形是倾斜的,这么做必错无疑
至于代码格式,虽然这么写可能会多占几行,但方便加注释了,至于为何x3,y3完了就是x5,y5,因为这是对角线,不是相邻的点

题解状态

136K,0MS,C++,1872B

题解代码

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
using namespace std;
#define INF 0x3f3f3f3f  
#define MAXN 16
#define memset0(a) memset(a,0,sizeof(a))
#define EPS 1e-6

inline int xp(int x1, int y1, int x2, int y2, int x3, int y3)
{
    return (x1 - x2)*(y3 - y2) - (y1 - y2)*(x3 - x2);
}
inline bool onsegment(int x, int y, int x1, int y1, int x2, int y2)
{
    return min(x1, x2) <= x&&x <= max(x1, x2) && min(y1, y2) <= y&&y <= max(y1, y2);
}
inline bool intersect(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4)
{
    int xp1 = xp(x3, y3, x1, y1, x2, y2);
    int xp2 = xp(x4, y4, x1, y1, x2, y2);
    int xp3 = xp(x1, y1, x3, y3, x4, y4);
    int xp4 = xp(x2, y2, x3, y3, x4, y4);
    if (xp1*xp2 < 0 && xp3*xp4 < 0)
        return 1;
    else if (!xp1&&onsegment(x3, y3, x1, y1, x2, y2))
        return 1;
    else if (!xp2&&onsegment(x4, y4, x1, y1, x2, y2))
        return 1;
    else if (!xp3&&onsegment(x1, y1, x3, y3, x4, y4))
        return 1;
    else if (!xp4&&onsegment(x2, y2, x3, y3, x4, y4))
        return 1;
    return 0;
}//上面三个函数完全是背模版
void fun(int x1, int y1, int x2, int y2, int x3, int y3, int x5, int y5)
{
    int x4 = x5, y4 = y3, x6 = x3, y6 = y5;//描绘出另一条对角线上两个点
    if (onsegment(x1, y1, x3, y3, x5, y5))
        printf("T\n");//output
    else if (onsegment(x2, y2, x3, y3, x5, y5))//这两个是判断线段任何一点在矩形内部
        printf("T\n");//output
    else if (intersect(x1, y1, x2, y2, x3, y3, x4, y4))
        printf("T\n");//output
    else if (intersect(x1, y1, x2, y2, x4, y4, x5, y5))
        printf("T\n");//output
    else if (intersect(x1, y1, x2, y2, x5, y5, x6, y6))
        printf("T\n");//output
    else if (intersect(x1, y1, x2, y2, x6, y6, x3, y3))//这四个是判断线段和矩形任何一边相交
        printf("T\n");//output
    else
        printf("F\n");//output
}
int main(void)
{
    //freopen("vs_cin.txt", "r", stdin);
    //freopen("vs_cout.txt", "w", stdout);

    int times;
    scanf("%d", &times);//input
    while (times--) {
        int x1, y1, x2, y2, x3, y3, x5, y5;//前4个描述线段 后4个描述矩形对角线
        scanf("%d%d%d%d%d%d%d%d", &x1, &y1, &x2, &y2, &x3, &y3, &x5, &y5);//input
        fun(x1, y1, x2, y2, x3, y3, x5, y5);
    }
}

EOF

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值