POJ
来源:互联网 发布:药品查询软件下载 编辑:程序博客网 时间:2024/05/21 08:57
点我看题
题意:给出一系列的线段,问是否存在一条直线,使得所有的线段在这条直线上的投影会交于一点。
分析:看完这个题,第一反应就想能不能转化为直线与线段的交,然后想去理清这个问题,画个图看看。
其中a为我们要找的直线,但是我们发现要判断是否存在一条a这样的直线是一件很困难的事情,因为我们没办法利用题目给的条件(n条线段的坐标),那么观察这个图,我们可以知道如果a存在,那么就一定存在与a垂直的一条直线b且b与其他n条线段有一个交点,那么整个题就转化为了问咱是否存在一条与其他n条线段都相交的线段。
那么我们可以一一枚举线段上这些点的两个端点形成一条直线,如果满足上述条件,则一定存在。
那么如何判断一条直线去某一线段是否相交呢那就要利用点的叉乘了,也就是线段Q1Q2的两个端点一定要在直线P1P2的左右两边,如下图
那么一定要满足(P1-Q1)×(p2-Q1)*(P1-Q2)×(P2-Q2) <= 0 才能表示直线与线段相交。
参考代码:
#include<cstdio>#include<cmath>#include<cstring>#include<algorithm>#include<iostream>using namespace std;#define eps 1e-8const int maxn = 1e2+5;int n;struct Point{ double x,y; Point(){} Point( double xx, double yy) { x = xx; y =yy; } Point operator - ( const Point &p)const { return Point(x-p.x,y-p.y); } //点的叉乘 double operator ^ ( const Point &p)const { return x*p.y-y*p.x; } //点的乘法(通常用于求两点距离) double operator * ( const Point p)const { return x*p.x+y*p.y; }};struct Line{ Point a,b; Line(){} Line( Point aa, Point bb) { a = aa; b = bb; }};Line line[maxn];//计算叉乘(p2-p1)*(p3-p1)double xmult( Point p1, Point p2, Point p3){ return (p2-p1)^(p3-p1);}//判断两点之间的距离double dist( Point p1, Point p2){ return sqrt((p2-p1)*(p2-p1));}int sgn( double x){ if( fabs(x) < eps) return 0; if( x < 0) return -1; return 1;}//判断直线和线段是否相交 l1为直线,l2为线段bool SegInterLine( Line l1, Line l2){// if( xmult(l1.a,l2.a,l1.b)*xmult(l1.a,l1.b,l2.b) < 0)//这也是可以的,kuangbin的写法// return false;// return true; if( xmult(l2.a,l1.a,l1.b)*xmult(l2.b,l1.a,l1.b) <= 0) return true; return false;}//判断p1p2是否与其他的线段相交bool check( Line l){ if( sgn(dist(l.a,l.b)) == 0)//两个点重合 return false; for( int i = 0; i < n; i++) { //判断直线和线段是否相交// if( xmult(p1,line[i].a,p2)*xmult(p1,p2,line[i].b) < 0)// return false; if( !SegInterLine(l,line[i])) return false; } return true;}int main(){ int T; scanf("%d",&T); while( T--) { scanf("%d",&n); double xa,ya,xb,yb; for( int i = 0; i < n; i++) { scanf("%lf%lf%lf%lf",&xa,&ya,&xb,&yb); line[i] = Line(Point(xa,ya),Point(xb,yb)); } bool flag = false; for( int i = 0; i < n; i++) { for( int j = 0; j < n; j++) { if( check(Line(line[i].a,line[j].a)) || check(Line(line[i].a,line[j].b)) || check(Line(line[i].b,line[j].a)) || check(Line(line[i].b,line[j].b))) { flag = true; break; } } } if( flag) puts("Yes!"); else puts("No!"); } return 0;}
阅读全文
0 0
- POJ
- poj
- POJ
- POJ
- poj
- poj
- POJ
- POJ
- poj
- POJ
- POJ
- POJ
- POJ
- POJ
- POJ
- POJ
- POJ
- POJ
- SpringBoot之Servlet(C)
- ubuntu下a2enmod命令的使用
- Java 中 Vector、ArrayList、List 使用深入剖析
- Spring整合JMS(消息中间件)
- SPFA
- POJ
- Node.js 实现爬虫(2) —— 多页面的爬虫程序
- Zigbee协议栈OSAL层API函数
- linux多命令小结
- hdu-4596(扩展欧几里得解一次不定方程)
- bzoj 3512: DZY Loves Math IV
- azkaban编译以及安装
- Spring AOP Schema aop:config、tx:advice
- C++:STL标准入门汇总