poj 3304——Segments
程序员文章站
2022-04-02 17:05:38
...
大致题意:给n条线段,判断是否存在一条线段,使得所有的线段在它上面的投影是否有公共交点。
大致思路:既然是投影,那很明显在纸上画一下就知道,以某条线段作为x轴建立直角坐标系,那就可以轻松的
画出每条线段在x轴上的投影,也就很容易就知道,判断投影有没有公共点,其实就是看有没有一条直线可以穿过所有的线段。
这里其实稍微跳了一点,但是画图就很容易知道我在说什么。看题目的数据范围n为100,所以暴力枚举任意两个的端点,判断这两个端点的直线是否可以穿过所有的线段。注:枚举的时候,如果两个端点的距离小于1e-8,就认为是同一个点,这次枚举的端点不算。
同时,通过上面的分析,大胆猜测口嗨一下,如果不考虑线段旋转的精度误差,应该可以枚举旋转线段,暴力判断所有线段的左端点的x坐标都小于min(所有线段的右端点的x坐标)。瞎吹一会,不要在意。
最后,代码:
#include<iostream>
#include<stdio.h>
#include<math.h>
using namespace std;
int n;
struct line
{
double x1,y1,x2,y2;
}lines[120];
double multiple_cross(double x1,double y1,double x2,double y2)
{
return x1*y2-x2*y1;
}
bool check(line a,line b)
{
double w,z;
w=multiple_cross(a.x1-b.x1,a.y1-b.y1,b.x2-b.x1,b.y2-b.y1);
z=multiple_cross(a.x2-b.x1,a.y2-b.y1,b.x2-b.x1,b.y2-b.y1);
if(w*z<=0)
return true;
return false;
}
bool judge(line ac)
{
if(sqrt((ac.x1-ac.x2)*(ac.x1-ac.x2)+(ac.y1-ac.y2)*(ac.y1-ac.y2))<1e-8)
return false;
bool flag=true;
for(int i=0;i<n;++i)
{
if(!check(lines[i],ac))
flag=false;
}
return flag;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
for(int i=0;i<n;++i)
{
scanf("%lf %lf %lf %lf",&lines[i].x1,&lines[i].y1,&lines[i].x2,&lines[i].y2);
}
if(n==1||n==2)
{
printf("Yes!\n");
continue;
}
line ac;
bool flag=false;
for(int i=0;i<n;++i)
{
for(int j=i+1;j<n;++j)
{
ac.x1=lines[i].x1,ac.y1=lines[i].y1;
ac.x2=lines[j].x1,ac.y2=lines[j].y1;
if(judge(ac))
{
flag=true;
}
ac.x2=lines[j].x2,ac.y2=lines[j].y2;
if(judge(ac))
{
flag=true;
}
ac.x1=lines[i].x2,ac.y1=lines[i].y2;
if(judge(ac))
{
flag=true;
}
ac.x2=lines[j].x1,ac.y2=lines[j].y1;
if(judge(ac))
{
flag=true;
}
}
}
if(flag)
printf("Yes!\n");
else
printf("No!\n");
}
return 0;
}
推荐阅读
-
POJ3252Round Numbers(数位dp)
-
kuangbin专题专题四 Frogger POJ - 2253
-
kuangbin专题 专题一 简单搜索 棋盘问题 POJ - 1321
-
kuangbin专题 专题一 简单搜索 Prime Path POJ - 3126
-
POJ:1017-Packets(贪心+模拟,神烦)
-
poj1637 Sightseeing tour(混合图欧拉回路)
-
POJ1862 Stripies 贪心 B
-
POJ2431 优先队列+贪心 - biaobiao88
-
POJ3233Matrix Power Series(矩阵快速幂)
-
4 Values whose Sum is 0 POJ - 2785