hduoj 1558 并查集、计算几何(判断两线断是否相交)

http://acm.hdu.edu.cn/showproblem.php?pid=1558
关于计算几何:判断两线断是否相交
* 返回(P1-P0)*(P2-P0)的叉积。 *
* 若结果为正,则 <P0,P1> 在 <P0,P2> 的顺时针方向; *
* 若为0则 <P0,P1> <P0,P2> 共线; *
* 若为负则 <P0,P1> 在 <P0,P2> 的在逆时针方向; *
* 可以根据这个函数确定两条线段在交点处的转向, *
* 比如确定p0p1和p1p2在p1处是左转还是右转,只要     *
*               求(p2-p0)*(p1-p0),若 <0则左转,> 0则右转,=0则   *
*               共线                                                                                     *
* *
/********************************************************/
/*float   multiply(TPoint   p1,TPoint   p2,TPoint   p0)
{
return((p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y));
}
 
 //确定两条线段是否相交
 int   intersect(TLineSeg   u,TLineSeg   v)
 {
 return(   (max(u.a.x,u.b.x)> =min(v.a.x,v.b.x))&&
 (max(v.a.x,v.b.x)> =min(u.a.x,u.b.x))&&
 (max(u.a.y,u.b.y)> =min(v.a.y,v.b.y))&&
 (max(v.a.y,v.b.y)> =min(u.a.y,u.b.y))&&
 (multiply(v.a,u.b,u.a)*multiply(u.b,v.b,u.a)> =0)&&
 (multiply(u.a,v.b,v.a)*multiply(v.b,u.b,v.a)> =0));
 }
*/
/*忘记了说明TPoint和TLineSeg的定义了:)
struct   TPoint   {
float   x,y;
};
  struct   TLineSeg   {
  TPoint   a,b;
  };
此题代码
#include<stdio.h> #define M 1001 typedef struct seg{ double x1,x2,y1,y2; }SEGMENT; SEGMENT s[M]; int parent[M]; int k; void init() {//init int i; k=0; for(i=0;i<M;i++) parent[i]=i; } double max(double x,double y) { return x>y?x:y; } double min(double x,double y) { return y<x?y:x; } double multiply(double x1,double y1,double x2,double y2,double x0,double y0) { return (x1-x0)*(y2-y0)-(x2-x0)*(y1-y0); } bool IsCon(SEGMENT a,SEGMENT b) { return ( max(a.x1,a.x2)>=min(b.x1,b.x2)&& max(b.x1,b.x2)>=min(a.x1,a.x2)&& max(a.y1,a.y2)>=min(b.y1,b.y2)&& max(b.y1,b.y2)>=min(a.y1,a.y2)&& multiply(a.x1,a.y1,b.x2,b.y2,b.x1,b.y1)*multiply(b.x2,b.y2,a.x2,a.y2,b.x1,b.y1)>=0&& multiply(b.x1,b.y1,a.x2,a.y2,a.x1,a.y1)*multiply(a.x2,a.y2,b.x2,b.y2,a.x1,a.y1)>=0 ); } int Root(int r) {//find the root of r if(parent[r]!=r) parent[r]=Root(parent[r]); return parent[r]; } void Merge(int a,int b) {//union the set of a and b a=Root(a);b=Root(b); if(a<b) parent[b]=a; else parent[a]=b; } void ComP() {//Commend of "P" int i; scanf("%lf%lf%lf%lf",&s[k].x1,&s[k].y1,&s[k].x2,&s[k].y2); for(i=0;i<=k;i++){ if(IsCon(s[k],s[i])){ Merge(i,k); } } k++; } void ComQ() {//Commend of "Q" int ith,i,ans=0,r; scanf("%d",&ith); r=Root(ith-1); for(i=0;i<k;i++){ // printf("%2d->%2d/n",i,Root(i)); if(Root(i)==r) ans++; } printf("%d/n",ans); } int main() {//main int t,n; char com[2]; scanf("%d",&t); while(t--){ scanf("%d",&n) ;init(); while(n--){ scanf("%s",com); switch(com[0]){ case 'P':ComP();break; case 'Q':ComQ(); } } if(t) puts(""); } return 0; }

你可能感兴趣的:(hduoj 1558 并查集、计算几何(判断两线断是否相交))