UVALive7461 - Separating Pebbles 判断两个凸包相交
//UVALive7461 - Separating Pebbles 判断两个凸包相交 #include <bits/stdc++.h>
using namespace std;
#define LL long long
typedef pair<int,int> pii;
const int inf = 0x3f3f3f3f;
const int N =1e5+;
#define clc(a,b) memset(a,b,sizeof(a))
const double eps = 1e-;
const int MOD = 1e9+;
void fre() {freopen("in.txt","r",stdin);}
void freout() {freopen("out.txt","w",stdout);}
inline int read() {int x=,f=;char ch=getchar();while(ch>''||ch<'') {if(ch=='-') f=-;ch=getchar();}while(ch>=''&&ch<='') {x=x*+ch-'';ch=getchar();}return x*f;} int sgn(double x) {
if(fabs(x) < eps)return ;
if(x < )return -;
else return ;
} struct Point {
int x,y;
Point() {}
Point(int _x,int _y) {
x = _x;
y = _y;
}
Point operator -(const Point &b)const {
return Point(x - b.x,y - b.y);
}
int operator ^(const Point &b)const {
return x*b.y - y*b.x;
}
int operator *(const Point &b)const {
return x*b.x + y*b.y;
}
friend int dis2(Point a) {
return a.x*a.x+a.y*a.y;
}
friend bool operator<(const Point &a,const Point &b){
if(fabs(a.y-b.y)<eps) return a.x<b.x;
return a.y<b.y;
}
};
typedef Point Vector;
double Dot(Point A, Point B){return A.x*B.x+A.y*B.y;}//点积
double Cross(Vector A,Vector B){return A.x*B.y-A.y*B.x;}//叉积
double Length(Vector A){return sqrt(Dot(A,A));}//OA长
double Angle(Point A,Point B){return acos(Dot(A,B)/Length(A)/Length(B));}//OA和OB的夹角
//判断线段相交,不在端点相交
bool SegmentProperIntersection(Point a1,Point a2,Point b1,Point b2){
double c1=Cross(a2-a1,b1-a1),c2=Cross(a2-a1,b2-a1),c3=Cross(b2-b1,a1-b1),c4=Cross(b2-b1,a2-b1);
return sgn(c1)*sgn(c2)<&&sgn(c3)*sgn(c4)<;
} int graham(Point p[],int n,Point q[]){
int top=;
sort(p,p+n);
if(n==) return ;
q[]=p[];
if(n==) return ;
q[]=p[];
if(n==) return ;
q[]=p[];
for(int i=;i<n;i++){
while(top&&(Cross(q[top]-q[top-],p[i]-q[top-])<=)) top--;
q[++top]=p[i];
}
int len=top;
q[++top]=p[n-];
for(int i=n-;i>=;i--){
while(top!=len&&(Cross(q[top]-q[top-],p[i]-q[top-])<=)) top--;
q[++top]=p[i];
}
return top;
} bool C_S(Point *ch1,int t1,Point *ch2,int t2)//判断凸包是否相交
{
double angle[],x;
int i,j,k,m;
if(t1==)return true;
if(t1==)
{
for(i=;i<t2;i++)
{
k=sgn(Cross(ch1[]-ch1[],ch2[i]-ch1[]));
if(k==&&Dot(ch1[]-ch1[],ch2[i]-ch1[])>)
{
if(Length(ch2[i]-ch1[])<Length(ch1[]-ch1[]))break;
}
}
if(i<t2)return false;
if(t2==&&SegmentProperIntersection(ch1[],ch1[],ch2[],ch2[]))return false;
return true;
}
angle[]=;
for(i=;i<t1;i++)
angle[i-]=Angle(ch1[]-ch1[],ch1[i]-ch1[]);
for(i=;i<t2;i++)
{
j=sgn(Cross(ch1[]-ch1[],ch2[i]-ch1[]));
if(j<||(j==&&Dot(ch1[]-ch1[],ch2[i]-ch1[])<))continue;
j=sgn(Cross(ch1[t1-]-ch1[],ch2[i]-ch1[]));
if(j>||(j==&&Dot(ch1[t1-]-ch1[],ch2[i]-ch1[])<))continue;
x=Angle(ch1[]-ch1[],ch2[i]-ch1[]);
m=lower_bound(angle,angle+t1-,x)-angle;
if(m==)j=;
else j=m-;
k=sgn(Cross(ch1[j+]-ch2[i],ch1[j+]-ch2[i]));
if(k>=)break;
}
if(i<t2)return false;
return true;
} Point p1[],p2[],ch1[],ch2[];
int main(){
int T;
scanf("%d",&T);
while(T--){
int n;
scanf("%d",&n);
int cnt1=,cnt2=;
for(int i=;i<n;i++){
int x,y,c;
scanf("%d%d%d",&x,&y,&c);
if(c==){
p1[cnt1++]=Point(x,y);
}
else p2[cnt2++]=Point(x,y);
}
int t1=graham(p1,cnt1,ch1);
int t2=graham(p2,cnt2,ch2);
if(C_S(ch1,t1,ch2,t2)&&C_S(ch2,t2,ch1,t1)) printf("1\n");
else printf("0\n");
}
}
UVALive7461 - Separating Pebbles 判断两个凸包相交的更多相关文章
- 如何判断单链表是否存在环 & 判断两链表是否相交
给定一个单链表,只给出头指针h: 1.如何判断是否存在环? 2.如何知道环的长度? 3.如何找出环的连接点在哪里? 4.带环链表的长度是多少? 解法: 1.对于问题1,使用追赶的方法,设定两个指针sl ...
- UVa 10256 (判断两个凸包相离) The Great Divide
题意: 给出n个红点,m个蓝点.问是否存在一条直线使得红点和蓝点分别分布在直线的两侧,这些点不能再直线上. 分析: 求出两种点的凸包,如果两个凸包相离的话,则存在这样一条直线. 判断凸包相离需要判断这 ...
- You can Solve a Geometry Problem too(判断两线段是否相交)
You can Solve a Geometry Problem too Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/3 ...
- Pick-up sticks--poj2653(判断两线段是否相交)
http://poj.org/problem?id=2653 题目大意:有n根各种长度的棍 一同洒在地上 求在最上面的棍子有那几个 分析: 我刚开始想倒着遍历 因为n是100000 想着会 ...
- NYOJ 1016 判断两线段是否相交
#include<cstdio> #include<cmath> #include<iostream> #include<algorithm> #inc ...
- HDU 6590 Code (判断凸包相交)
2019 杭电多校 1 1013 题目链接:HDU 6590 比赛链接:2019 Multi-University Training Contest 1 Problem Description Aft ...
- You can Solve a Geometry Problem too (hdu1086)几何,判断两线段相交
You can Solve a Geometry Problem too Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/3276 ...
- hdu 1086:You can Solve a Geometry Problem too(计算几何,判断两线段相交,水题)
You can Solve a Geometry Problem too Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/3 ...
- UVa 10256 - The Great Divide 判断凸包相交
模板敲错了于是WA了好几遍…… 判断由红点和蓝点分别组成的两个凸包是否相离,是输出Yes,否输出No. 训练指南上的分析: 1.任取红凸包上的一条线段和蓝凸包上的一条线段,判断二者是否相交.如果相交( ...
随机推荐
- redis 配置文件aof配置
redis 配置文件aof配置: bind 127.0.0.1 port 6379 daemonize yes dbfilename dump.rdb dir /new_renpeng/redis/ ...
- Selenium3 + Python3自动化测试系列七——多窗口切换
多窗口切换 在页面操作过程中有时候点击某个链接会弹出新的窗口,这时就需要主机切换到新打开的窗口上进行操作. WebDriver提供了switch_to.window()方法,可以实现在不同的窗口之间切 ...
- Linux初学习之 rm 命令
现在我们来仔细的学习一下linux的rm命令,这个命令顾名思义(我猜的,嘻嘻,是remove) 命令格式: rm [OPTION]... FILE... Remove (unlink) the FIL ...
- git的指令的一张很好的图
非常好的一张图
- windows 和 linux 多线程
学习了几天多线程技术,做个总结,便于记忆. 一般 多线程传递参数 为 void* 所以会有一个强制转换过程 (int*) (void *)等,传递多个参数选择 结构体指针.为了避免多个线程访问数据 ...
- Linux常用命令大全(很全面)
最近都在和Linux打交道,感觉还不错.我觉得Linux相比windows比较麻烦的就是很多东西都要用命令来控制,当然,这也是很多人喜欢linux的原因,比较短小但却功能强大.我将我了解到的命令列举一 ...
- delphi中TreeView使用(转)
delphi中TreeView使用(1) TreeView由节点构成,建树通过对TreeView.items属性进行操作.Items是一个TTreeNodes对象,这是一个TTreeNode集. 一. ...
- Delphi 中多线程同步的一些处理方法
Delphi 中多线程同步的一些处理方法 当创建了多个线程,并且多个线程都要访问同一资源,,就有可能出现混乱,于是用Synchronize来控制,使同一时间只有一个线程使用那部分资源,Synchr ...
- 帝国cms简介显示转义字符问题
在模板中设置简介截取字数为0,前端显示用css控制即可 white-space: nowrap; overflow: hidden; text-overflow: ellipsis; 也可以 1,在后 ...
- 「题解」:07.16NOIP模拟T2:通讯
问题 B: 通讯 时间限制: 1 Sec 内存限制: 256 MB 题面 题目描述 “这一切都是命运石之门的选择.” 试图研制时间机器的机关SERN截获了中二科学家伦太郎发往过去的一条短 信,并由此 ...