2984. 线段

题目链接

2984. 线段

在二维平面内有 n 条线段,请你编写一个程序,判断是否存在一条直线满足将这 n 条线段投影到该直线上后,所有的投影线段至少具有一个公共点。

输入格式

第一行包含整数 T,表示共有 T 组测试数据。

每组数据第一行包含整数 n,表示共有 n 条线段。

接下来 n 行,每行包含四个实数 x1,y1,x2,y2,其中 (x1,y1)(x2,y2) 是一条线段的两端点坐标。

输出格式

对于每组数据,如果存在满足条件的线段,则输出一行 Yes!,否则输出一行 No!

如果两个浮点数 ab 满足 |ab|<108,则你可以认为这两个数相等。

数据范围

1T100,
1n100,
109x1,y1,x2,y2109

输入样例:

3 2 1.0 2.0 3.0 4.0 4.0 5.0 6.0 7.0 3 0.0 0.0 0.0 1.0 0.0 1.0 0.0 2.0 1.0 1.0 2.0 1.0 3 0.0 0.0 0.0 1.0 0.0 2.0 0.0 3.0 1.0 1.0 2.0 1.0

输出样例:

Yes! Yes! No!

解题思路

计算几何

问题等价于判断是否存在一条直线能否穿过所有线段,假设存在这样一条直线,则该直线一定可以通过旋转且穿过所有线段的前提下穿过某条线段的某个端点,同理,到达该端点后还可以到达另外一个端点,即这样的直线可以通过已知的端点构造出来,暴力所有这样的直线,然后通过叉积判断是否所有的线段的两个端点都在直线两侧

  • 时间复杂度:O(n3)

代码

// Problem: 线段 // Contest: AcWing // URL: https://www.acwing.com/problem/content/description/2987/ // Memory Limit: 64 MB // Time Limit: 2000 ms // // Powered by CP Editor (https://cpeditor.org) // %%%Skyqwq #include <bits/stdc++.h> //#define int long long #define help {cin.tie(NULL); cout.tie(NULL);} #define pb push_back #define fi first #define se second #define mkp make_pair using namespace std; typedef long long LL; typedef pair<int, int> PII; typedef pair<LL, LL> PLL; template <typename T> bool chkMax(T &x, T y) { return (y > x) ? x = y, 1 : 0; } template <typename T> bool chkMin(T &x, T y) { return (y < x) ? x = y, 1 : 0; } template <typename T> void inline read(T &x) { int f = 1; x = 0; char s = getchar(); while (s < '0' || s > '9') { if (s == '-') f = -1; s = getchar(); } while (s <= '9' && s >= '0') x = x * 10 + (s ^ 48), s = getchar(); x *= f; } const int N=105; const double eps=1e-8; typedef pair<double,double> PDD; int t,n; PDD a[N],b[N],c[N<<1]; int sign(double x) { if(fabs(x)<eps)return 0; if(x>0)return 1; return -1; } int cmp(double x,double y) { if(fabs(x-y)<eps)return 0; if(x>y)return 1; return -1; } double cross(double x1,double y1,double x2,double y2) { return x1*y2-x2*y1; } double area(PDD a,PDD b,PDD c) { return cross(b.fi-a.fi,b.se-a.se,c.fi-a.fi,c.se-a.se); } bool ck() { for(int i=1;i<=2*n;i++) for(int j=i+1;j<=2*n;j++) { if(!cmp(c[i].fi,c[j].fi)&&!cmp(c[i].se,c[j].se))continue; bool f=true; for(int k=1;k<=n;k++) if(sign(area(c[i],c[j],a[k]))*sign(area(c[i],c[j],b[k]))>0) { f=false; break; } if(f)return true; } return false; } int main() { for(cin>>t;t;t--) { cin>>n; for(int i=1;i<=n;i++) { cin>>a[i].fi>>a[i].se>>b[i].fi>>b[i].se; c[i]=a[i],c[i+n]=b[i]; } puts(ck()?"Yes!":"No!"); } return 0; }

__EOF__

本文作者acwing_zyy
本文链接https://www.cnblogs.com/zyyun/p/16893211.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   zyy2001  阅读(43)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示