• hdu1558--并查集+判断线段相交


    简单的计算几何题,判断两线段是否相交。将相交的两线段使用并查集归到一类中。查询时输出线段对应集合中元素的个数。

    #include<stdio.h>
    
    struct Point{
    	double x,y;
    };
    struct Segment{
    	Point s,e;
    }node[1010];
    int n,parent[1010];
    int getAbs(int value)
    {
    	if(value>=0)return value;
    	return -value;
    }
    int getParent(int a){
    	while(parent[a]>0)a=parent[a];
    	return a;
    }
    void Union(int a,int b)
    {
    	int r1 = getParent(a);
    	int r2 = getParent(b);
    	if(r1!=r2)
    	{
    		if(r1<r2)
    		{
    			parent[r1]+=parent[r2];//合并两个集合时,计算两个集合的元素个数
    			parent[r2]=r1;
    		}else{
    			parent[r2]+=parent[r1];
    			parent[r1]=r2;
    		}
    	}
    }
    double max(double a,double b)
    {
    	if(a>=b)return a;
    	return b;
    }
    double min(double a,double b)
    {
    	if(a>=b)return b;
    	return a;
    }
    /** 
    * 计算向量 ps,pe的叉积
    */
    double multiply(Point p,Point s,Point e)
    {
    	return (s.x-p.x)*(e.y-p.y)-(e.x-p.x)*(s.y-p.y);
    }
    int main()
    {
    	int t,n,i,j,num,cnt;
    	char command;
    	scanf("%d",&t);
    	while(t--)
    	{
    		scanf("%d",&n);
    		cnt=0;
    		//初始时每个元素都是一个集合
    		for(i=1;i<=n;i++)parent[i]=-1;
    		for(i=1;i<=n;i++)
    		{
    			getchar();
    			scanf("%c",&command);
    			if(command=='P'){
    				cnt++;
    				scanf("%lf%lf%lf%lf",&node[cnt].s.x,&node[cnt].s.y,&node[cnt].e.x,&node[cnt].e.y);
    				for(j=1;j<cnt;j++)
    				{
    					//判断第cnt个线段是否与前面的cnt-1个线段有相交。
    					if(max(node[cnt].s.x,node[cnt].e.x)>=min(node[j].s.x,node[j].e.x)
    						&& max(node[j].s.x,node[j].e.x)>=min(node[cnt].s.x,node[cnt].e.x)
    						&& max(node[cnt].s.y,node[cnt].e.y)>=min(node[j].s.y,node[j].e.y)
    						&& max(node[j].s.y,node[j].e.y)>=min(node[cnt].s.y,node[cnt].e.y)
    						&& multiply(node[cnt].s,node[j].s,node[j].e)*multiply(node[cnt].e,node[j].s,node[j].e)<=0
    						&& multiply(node[j].s,node[cnt].s,node[cnt].e)*multiply(node[j].e,node[cnt].s,node[cnt].e)<=0)
    					{
    						//有相交就合并集合
    						Union(cnt,j);
    					}
    				}
    			}else
    			{
    				scanf("%d",&num);
    				//当parent为负数时,其绝对值就是该集合的元素个数。
    				printf("%d
    ",getAbs(parent[getParent(num)]));
    			}
    		}
    		if(t!=0)
    		{
    			printf("
    ");
    		}
    	}
    	return 0;
    }


  • 相关阅读:
    JS 数组排序
    曾经跳过的坑------replace、替换斜杠反斜杠、时间格式化处理
    List排序、集合排序
    git远程覆盖本地的
    整理日期,整理时间段,将日期集合整理为时间段
    当数据库查询in使用超过1000个的处理方式,in超过1000的问题
    oracle一些语法
    idea中git操作
    idea鼠标放上去查看注释,idea查看注释
    idea更新git远程代码,查看代码改动了哪些
  • 原文地址:https://www.cnblogs.com/snake-hand/p/3180096.html
Copyright © 2020-2023  润新知