//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 判断两个凸包相交的更多相关文章

  1. 如何判断单链表是否存在环 & 判断两链表是否相交

    给定一个单链表,只给出头指针h: 1.如何判断是否存在环? 2.如何知道环的长度? 3.如何找出环的连接点在哪里? 4.带环链表的长度是多少? 解法: 1.对于问题1,使用追赶的方法,设定两个指针sl ...

  2. UVa 10256 (判断两个凸包相离) The Great Divide

    题意: 给出n个红点,m个蓝点.问是否存在一条直线使得红点和蓝点分别分布在直线的两侧,这些点不能再直线上. 分析: 求出两种点的凸包,如果两个凸包相离的话,则存在这样一条直线. 判断凸包相离需要判断这 ...

  3. 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 ...

  4. Pick-up sticks--poj2653(判断两线段是否相交)

    http://poj.org/problem?id=2653 题目大意:有n根各种长度的棍   一同洒在地上 求在最上面的棍子有那几个 分析:  我刚开始想倒着遍历  因为n是100000   想着会 ...

  5. NYOJ 1016 判断两线段是否相交

    #include<cstdio> #include<cmath> #include<iostream> #include<algorithm> #inc ...

  6. HDU 6590 Code (判断凸包相交)

    2019 杭电多校 1 1013 题目链接:HDU 6590 比赛链接:2019 Multi-University Training Contest 1 Problem Description Aft ...

  7. 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 ...

  8. 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 ...

  9. UVa 10256 - The Great Divide 判断凸包相交

    模板敲错了于是WA了好几遍…… 判断由红点和蓝点分别组成的两个凸包是否相离,是输出Yes,否输出No. 训练指南上的分析: 1.任取红凸包上的一条线段和蓝凸包上的一条线段,判断二者是否相交.如果相交( ...

随机推荐

  1. hadoop命令行

    持续更新中................ 1. 设置目录配额 命令:hadoop dfsadmin -setSpaceQuota 样例:hadoop dfsadmin -setSpaceQuota ...

  2. 第一周 Largest Rectangle in a Histogram

    Language: 题目: Largest Rectangle in a Histogram Time Limit: 1000MS   Memory Limit: 65536K Total Submi ...

  3. 3-vim-打开和新建文件-02-删除交换文件

    vim的异常处理 如果vim异常退出,在磁盘上可能会保存有交换文件. 若使用vi编辑该文件时看到如下图信息,按下字母d就可以删除交换文件. 注意:输入命令操作的时候关闭输入法.

  4. react 父子组件传值

    父组件向子组件传递信息 父组件片段 constructor(props){ super(props) this.state={ message:"我是父组件传来的" } } ren ...

  5. 遍历对象不能通过for循环因为对象无序 可以通过for -n

    遍历对象不能通过for循环因为对象无序  可以通过for -n var json={ "name":“小明”, “age”:“10”, “sex”:"男" }; ...

  6. vue tabNav 点击

    <template> <div class="content"> <header class="tab_nav"> < ...

  7. Redis探索之路(六):Redis的常用命令

    一:键值相关命令 1.keys Pattern模糊查询 keys my* 2.exists某个key是否存在 exists key1 3.del 删除一个key del key1 4.expire设置 ...

  8. R语言 变量

    R语言变量 变量为我们提供了我们的程序可以操作的命名存储. R语言中的变量可以存储原子向量,原子向量组或许多Robject的组合. 有效的变量名称由字母,数字和点或下划线字符组成. 变量名以字母或不以 ...

  9. AnalyticDB for PostgreSQL 6.0 新特性介绍

    阿里云 AnalyticDB for PostgreSQL 为采用MPP架构的分布式集群数据库,完备支持SQL 2003,部分兼容Oracle语法,支持PL/SQL存储过程,触发器,支持标准数据库事务 ...

  10. thinkphp Widget扩展

    Widget扩展一般用于页面组件的扩展.大理石平台规格 举个例子,我们在页面中实现一个分类显示的Widget,首先我们要定义一个Widget控制器层 CateWidget,如下: namespace ...