zoukankan      html  css  js  c++  java
  • 【计算几何初步-线段相交+并查集】【HDU1558】Segment set

    Segment set

    Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 3548    Accepted Submission(s): 1324


    Problem Description
    A segment and all segments which are connected with it compose a segment set. The size of a segment set is the number of segments in it. The problem is to find the size of some segment set.

     

    Input
    In the first line there is an integer t - the number of test case. For each test case in first line there is an integer n (n<=1000) - the number of commands. 

    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.
     

    Output
    For each Q-command, output the answer. There is a blank line between test cases.
     

    Sample Input
    1 10 P 1.00 1.00 4.00 2.00 P 1.00 -2.00 8.00 4.00 Q 1 P 2.00 3.00 3.00 1.00 Q 1 Q 3 P 1.00 4.00 8.00 2.00 Q 2 P 3.00 3.00 6.00 -2.00 Q 5
     

    Sample Output
    1 2 2 2 5
     

    Author
    LL
     



    主要可能会直线重叠的情况,此时也算相交

    所以若叉积为0 点积也为0时也算相交

    代码如下:

    #include <cstdio>  
    #include <cstdlib>  
    #include <cmath>  
    #include <cstring>  
    #include <ctime>  
    #include <algorithm>  
    #include <iostream>
    #include <sstream>
    #include <string>
    #define oo 0x13131313   
    #define exp 0.000001
    using namespace std;
    int N,tot;
    struct point
    {
    	double x,y;
    };
    point S[10110],E[10011];
    int Set[10110];
    int ANS[10110];
    int sgn(double x)
    {
    	if(fabs(x)<exp) return 0;
    	else if(x<0) return -1;
    	else return 1;
    }
    double dotdet(double x1,double y1,double x2,double y2)
    {
    	return x1*x2+y1*y2;
    }
    double dot(point a,point b,point c)
    {
    	return dotdet(b.x-a.x,b.y-a.y,c.x-a.x,c.y-a.y);
    }
    double crossdet(double x1,double y1,double x2,double y2)
    {
    	return x1*y2-x2*y1;
    }
    double cross(point a,point b,point c)
    {
    	return crossdet(b.x-a.x,b.y-a.y,c.x-a.x,c.y-a.y);
    }
    double pan(point s1,point e1,point s2,point e2)
    {
    	//跨立实验 
    	double a1=cross(s1,e1,s2);  //s1-e1 s2
    	double a2=cross(s1,e1,e2);
    	double a3=cross(s2,e2,s1);
    	double a4=cross(s2,e2,e1);
    	if(sgn(a1*a2)<0&&sgn(a3*a4)<0) return 1;
    	if((a1==0&&sgn(dot(s2,s1,e1))<=0)||
    	   (a2==0&&sgn(dot(e2,s1,e1))<=0)||
    	   (a3==0&&sgn(dot(s1,s2,e2))<=0)||
    	   (a4==0&&sgn(dot(e1,s2,e2))<=0))
    	   return 1;
    	return 0;
    }
    void CSH()
    {
    	for(int i=0;i<=10001;i++)
    	{
    	Set[i]=i;
    	ANS[i]=1;
    	}
    	tot=0;
    }
    int find(int x)
    {
    	if(x!=Set[x]) 
    	Set[x]=find(Set[x]);
    	return Set[x];
    }
    void UNION(int a,int b)
    {
    	int a1=find(a);
    	int a2=find(b);
    	if(a1!=a2)
    	{	
    		ANS[a1]+=ANS[a2];
    		Set[a2]=a1;
    	}
    }
    void input()
    {
    	char ch;int temp;
    	CSH();
    	cin>>N;
    	getchar();
    	for(int i=1;i<=N;i++)
    	{
            scanf("%c",&ch);
    		if(ch=='P')
    		{
    			tot++; 
    			scanf("%lf%lf%lf%lf
    ",&S[tot].x,&S[tot].y,&E[tot].x,&E[tot].y);
    			for(int i=1;i<tot;i++)
    			{
    				if(pan(S[i],E[i],S[tot],E[tot])==1)
    				{
    					UNION(i,tot);
    				}	
    			}
    		}
    		else if(ch=='Q')
    		{
    			scanf("%d
    ",&temp);
    			cout<<ANS[find(temp)]<<endl;
    		}
    	}
    }
    void init()
    {
    	freopen("a.in","r",stdin);
    	freopen("a.out","w",stdout); 
    }
    int main()
    {
    	int T;
    //	init();
    	cin>>T;
    	int nn=0;
    	while(T--)
    	{
    		if(nn++) cout<<endl;
    		input();		
    	}
    	return 0;
    }
      


  • 相关阅读:
    JS中所有数组的方法和所有的对象方法,包含ES5和ES6
    (原创!)彻底理解JS中的事件,事件处理函数,钩子函数,回调函数。
    深拷贝和浅拷贝的区别,object.assgin方法是深拷贝还是浅拷贝
    axios,Ajax,jQuery ajax,axios和fetch的区别
    python : 文档比较
    leetcode——989.数组形式的整数加法
    leetcode——66.加一
    leetcode——283.移动0
    leetcode——27.移除元素
    leetcode刷题第一天——两数之和
  • 原文地址:https://www.cnblogs.com/zy691357966/p/5480424.html
Copyright © 2011-2022 走看看