线段相交(10分) 51Nod

来源:互联网 发布:linux 设置命令别名 编辑:程序博客网 时间:2024/06/06 00:34

给出平面上两条线段的两个端点,判断这两条线段是否相交(有一个公共点或有部分重合认为相交)。 如果相交,输出"Yes",否则输出"No"。
Input
    第1行:一个数T,表示输入的测试数量(1 <= T <= 1000)
    第2 - T + 1行:每行8个数,x1,y1,x2,y2,x3,y3,x4,y4。(-10^8 <= xi, yi <= 10^8)
    (直线1的两个端点为x1,y1 | x2, y2,直线2的两个端点为x3,y3 | x4, y4)
Output
    输出共T行,如果相交输出"Yes",否则输出"No"。
Sample Input

    2
    1 2 2 1 0 0 2 2
    -1 1 1 1 0 0 1 -1

Sample Output

    Yes
    No


题解:判断两个线段是否相交,可以转换为判断一直线与一线段是否相交即只需判断线段两端点是否在直线的两侧,这个需要用到高数中的向量。具体知识点如下:

如果s(A,B,C)>0 则C在向量AB 的左侧;

如果s(A,B,C)<0 则C在向量AB 的右侧;

如果s(A,B,C)=0 则C在向量AB 上;

假设有三点P1(X1,Y1),P2(X2,Y2),P3(X3,Y3),s(P1,P2,P3)=向量P1P2 叉乘 向量P3P2;

所以:s(P1,P2,P3)=(X2-X1)*(Y2-Y3)-(Y2-Y1)*(X2-X3);

具体代码如下:


#include<stdio.h>#include<string.h>double check(double x1,double y1,double x2,double y2,double x,double y){    return (x2-x1)*(y2-y)-(y2-y1)*(x2-x);}int main(){    int t;    scanf("%d",&t);    while(t--)    {        double t1=0,t2=0,t3,t4;        double x1,y1,x2,y2,x3,y3,x4,y4;        scanf("%lf%lf%lf%lf%lf%lf%lf%lf",&x1,&y1,&x2,&y2,&x3,&y3,&x4,&y4);        t1=check(x1,y1,x2,y2,x3,y3);        t2=check(x1,y1,x2,y2,x4,y4);        t3=check(x3,y3,x4,y4,x1,y1);        t4=check(x3,y3,x4,y4,x2,y2);        if(t1*t2<=0 && t3*t4<=0)            printf("Yes\n");        else            printf("No\n");    }    return 0;}


阅读全文
'); })();
0 0
原创粉丝点击
热门IT博客
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 大众汽车捷达多少钱 捷达2000 柴油版捷达 2013捷达 大众汽车捷达报价 捷达摩托车 捷达维修 大众捷达桑塔纳 捷达双燃料 捷达 爱丽舍 二手的捷达 捷达钢圈 捷达方向机 大众捷达和桑塔纳哪个好 二手 捷达 捷达汽车改装 大众新款捷达怎么样 捷达国际运输公司 捷达2011 捷达汽车好吗 大众捷达图片及报价 一汽大众捷达降价 2013捷达报价 14款捷达 二手捷达汽车 改装捷达图片 捷达汽车自动挡 捷达 威驰 捷达昕锐 捷达专卖店 捷达柴油车价格 捷达伙伴改装 二手捷达前卫 捷达车友会 速腾 捷达 大众捷达两厢车 捷达自动挡汽车 大众捷达的价格 海外版捷达 大众新款捷达图片 国外捷达