ACM1558两线段相交判断和并查集
Segment set
There are two different commands described in different format shown below:
P x1 y1 x2 y2 - paint a segment whose coordinates of the two endpoints are (x1,y1),(x2,y2).
Q k - query the size of the segment set which contains the k-th segment.
k is between 1 and the number of segments in the moment. There is no segment in the plane at first, so the first command is always a P-command.
P 2.00 3.00 3.00 1.00
本题主要难关是判断量条线段是否相交,在我这篇文章里有详细介绍判断两条线段相交的方法。http://www.cnblogs.com/sytu/articles/3876585.html;
Notice:二维向量的叉乘公式是 axb=(x1,y1)x(x2,y2)=x1*y2-y1*x2;
下面为AC代码:
#include<iostream>
using namespace std;
#define MIN(x,y) (x < y ? x : y)
#define MAX(x,y) (x > y ? x : y)
typedef struct
{
double x,y;
} Point;
struct LINE
{
double x1,x2,y1,y2;
int flag;
};
LINE *line;
int lineintersect(int a,int b)
{
Point p1,p2,p3,p4;
p1.x=line[a].x1;p1.y=line[a].y1;
p2.x=line[a].x2;p2.y=line[a].y2;
p3.x=line[b].x1;p3.y=line[b].y1;
p4.x=line[b].x2;p4.y=line[b].y2; Point tp1,tp2,tp3,tp4,tp5,tp6;
if ((p1.x==p3.x&&p1.y==p3.y)||(p1.x==p4.x&&p1.y==p4.y)||(p2.x==p3.x&&p2.y==p3.y)||(p2.x==p4.x&&p2.y==p4.y))
return ;
//快速排斥试验
if(MAX(p1.x,p2.x)<MIN(p3.x,p4.x)||MAX(p3.x,p4.x)<MIN(p1.x,p2.x)||MAX(p1.y,p2.y)<MIN(p3.y,p4.y)||MAX(p3.y,p4.y)<MIN(p1.y,p2.y))
return ;
//跨立试验
tp1.x=p1.x-p3.x;
tp1.y=p1.y-p3.y;
tp2.x=p4.x-p3.x;
tp2.y=p4.y-p3.y;
tp3.x=p2.x-p3.x;
tp3.y=p2.y-p3.y;//从这到上面是一组的向量
tp4.x=p2.x-p4.x;//下面是一组的向量
tp4.y=p2.y-p4.y;
tp5.x=p2.x-p3.x;
tp5.y=p2.y-p3.y;
tp6.x=p2.x-p1.x;
tp6.y=p2.y-p1.y;
if ((tp1.x*tp2.y-tp1.y*tp2.x)*(tp2.x*tp3.y-tp2.y*tp3.x)>=) //此处用到了叉乘公式
{
if((tp4.x*tp6.y-tp4.y*tp6.x)*(tp6.x*tp5.y-tp6.y*tp5.x)>=)
return ;
}
return ;
}
int find(int x)
{
if(>line[x].flag)return x;
return line[x].flag=find(line[x].flag);
}
void Union(int a,int b)
{
int fa=find(a);
int fb=find(b);
if(fa==fb)return;
int n1=line[fa].flag;
int n2=line[fb].flag;
if(n1>n2)
{
line[fa].flag=fb;
line[fb].flag+=n1;
}
else
{
line[fb].flag=fa;
line[fa].flag+=n2;
}
}
void throwinto(int n)
{
if(n>)
{
for(int i=;i<n;i++)
{
if(lineintersect(i,n))
Union(i,n);
}
}
}
int main()
{
int t;
cin>>t;
int n,q;
int cn=t;
while(t--)
{ int cnt=;
cin>>n;
line=new LINE[n+];
for(int i=;i<=n;i++)
{
line[i].flag=-;
}
for(int i=;i<=n;i++)
{
char sj;
cin>>sj;
if(sj=='P')
{
cin>>line[cnt].x1>>line[cnt].y1>>line[cnt].x2>>line[cnt].y2;
throwinto(cnt);
cnt++;
}
else if(sj=='Q')
{
cin>>q;
int re=find(q);
cout<<-line[re].flag<<endl;
}
}
if(t>)cout<<endl;//注意格式问题,容易出错
}
return ;
}
ACM1558两线段相交判断和并查集的更多相关文章
- poj 1127:Jack Straws(判断两线段相交 + 并查集)
Jack Straws Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 2911 Accepted: 1322 Descr ...
- 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 1147:Pick-up sticks(基本题,判断两线段相交)
Pick-up sticks Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)To ...
- POJ_1227 Jack Straws 【二维平面判两线段相交】
一 题面 POJ1127 二 分析 在平面几何中,判断两线段相交的方法一般是使用跨立实验.但是这题考虑了非严格相交,即如何两个线段刚好端点相交则也是相交的,所以还需要使用快速排斥实验. 这里参考并引用 ...
- 【BZOJ4025】二分图(线段树分治,并查集)
[BZOJ4025]二分图(线段树分治,并查集) 题面 BZOJ 题解 是一个二分图,等价于不存在奇环. 那么直接线段树分治,用并查集维护到达根节点的距离,只计算就好了. #include<io ...
- 【CF938G】Shortest Path Queries(线段树分治,并查集,线性基)
[CF938G]Shortest Path Queries(线段树分治,并查集,线性基) 题面 CF 洛谷 题解 吼题啊. 对于每个边,我们用一个\(map\)维护它出现的时间, 发现询问单点,边的出 ...
- poj 1127 -- Jack Straws(计算几何判断两线段相交 + 并查集)
Jack Straws In the game of Jack Straws, a number of plastic or wooden "straws" are dumped ...
- 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 ...
- POJ 3449 Geometric Shapes(判断几个不同图形的相交,线段相交判断)
Geometric Shapes Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 1243 Accepted: 524 D ...
随机推荐
- appcrawler遍历工具常用方法
Usage: appcrawler [options] -a, --app <value> Android或者iOS的文件地址, 可以是网络地址, 赋值给appium的app选项 -c, ...
- CodeForces 908C. New Year and Curling 解题报告 Java
1. 思路 这题实际上是个几何问题——两个外相切的圆,由勾股定理,他们的纵坐标有以下的规律: 则有$$y_{n+1} = y_{n} + \sqrt{(2r)^2 - (x_{n} - x_{n+1} ...
- how to install pygraphviz on windows 10 with python 3.6
Here's what worked for me: Win 7 AMD64 Install MSFT C++ compiler. Install Anaconda for Win AMD64, Py ...
- Median of Two Sorted Arrays(hard)
题目要求: 有两个排序的数组nums1和nums2分别为m和n大小. 找到两个排序数组的中位数.整体运行时间复杂度应为O(log(m + n)). 示例: 我的方法: 分别逐个读取两个数组的数,放到一 ...
- alpha阶段个人总结(201521123034陈凯欣)
一.个人总结 第 0 部分:基本数据结构和算法问题 大二的时候上过数据结构课,感觉自己没有学的太深入,就如之前结对编程时候四则运算有用到的二叉树来解决问题,对于二叉树就有个模糊的概念,实际动手操作起来 ...
- tweenjs缓动算法使用小实例
这里的tweenjs不是依托于createjs的tewwnjs,而是一系列缓动算法集合.因为本身是算法,可以用在各个业务场景中,这也正是总结学习它的价值所在.tweenjs代码详情: /* * Twe ...
- 第61天:json遍历和封装运动框架(多个属性)
一.json 遍历 for in 关键字 for ( 变量 in 对象) { 执行语句; } 例如: var json = {width:200,height:300,left:50}co ...
- Hadoop——HDFS的构架
在使用一个工具之前,应该先对它的机制.组成等有深入的了解,以后才会更好的使用它.下面来介绍一下什么是HDFS,以及他的构架是什么样的. 1.什么是HDFS? Hadoop主要是用于进行大数据处理,那么 ...
- Oracle 转义字符
id sfds_V_SF ASD_V_DSAF SD_V_DSAD 下划线是Oracle特殊字符,需要转移,如下 select * from systab t where t.id like ...
- [LOJ #6433]「PKUSC2018」最大前缀和
题目大意:给你一个$n(n\leqslant20)$项的数列$A$,设重排后的数列为$A'$,令$pre_p=\sum\limits_{i=1}^pA'_i$,求$max\{pre_i\}$的期望,乘 ...