hdu1558 Segment set

来源:互联网 发布:caffe在windows安装 编辑:程序博客网 时间:2024/05/16 17:51
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
110P 1.00 1.00 4.00 2.00P 1.00 -2.00 8.00 4.00Q 1P 2.00 3.00 3.00 1.00Q 1Q 3P 1.00 4.00 8.00 2.00Q 2P 3.00 3.00 6.00 -2.00Q 5
 

Sample Output
1
2225
这题可以用并查集做,主要是要判断两条线段是不是相交,我的方法是记两条线段的端点是p1(x1,y1),p2(x2,y2)以及p3(x3,y3),p4(x4,y4),分别看4个端点有没有在另一条线段上,如果有,那么相交,如果没有,那么再用叉积判断每条线段的两个端点是不是在另一条线段的两边,如果p1,p2在线段p3p4的两边而且p3,p4在线段p1p2的两边,那么p1p2和p3p4相交,否则不相交。那么怎么判断p1,p2是否在线段p3p4的两边呢,这里用到了叉积,第一次取p1,p3,p4,如果向量p1p3和向量p1p4的叉积是正的,那么p1p2在p3p4的顺时针方向,反之在逆时针方向。再取p2,p3,p4,方法相同,如果两个叉积符号不同,那么p1,p2在线段p3p4的两边,否则不在。
#include<stdio.h>#include<string.h>#include<math.h>int pre[1006];int find(int x){    int r=x;    while(r!=pre[r])r=pre[r];    return r;}int shizhen(double x2,double y2,double x4,double y4,double x5,double y5){    double x=x4-x2,y=y4-y2,xx=x5-x2,yy=y5-y2;    if(x*yy-xx*y>0)return 1;    else return -1;}int xianshang(double x2,double y2,double x3,double y3,double x4,double y4){    if((x2-x3)*(y4-y2)-(y2-y3)*(x4-x2)!=0)return 0;    if((x2<x3 && x2<x4) || (x2>x3 && x2>x4))return 0;    return 1;}int panduan(double x2,double y2,double x3,double y3,double x4,double y4,double x5,double y5){    if(xianshang(x2,y2,x4,y4,x5,y5) || xianshang(x3,y3,x4,y4,x5,y5) || xianshang(x4,y4,x2,y2,x3,y3) || xianshang(x5,y5,x2,y2,x3,y3))return 1;    if((shizhen(x2,y2,x4,y4,x5,y5)*shizhen(x3,y3,x4,y4,x5,y5)<0)  && (shizhen(x4,y4,x2,y2,x3,y3)*shizhen(x5,y5,x2,y2,x3,y3)<0))return 1;    return 0;}int main(){    int T,n,m,i,j,a,t1,xianduan[1006],num[1005],num1,h;    double x2[1006],x3[1006],y2[1006],y3[1006];    char s[10];    scanf("%d",&T);    for(h=1;h<=T;h++)    {        scanf("%d",&n);        num1=0;        for(i=1;i<=n;i++){            pre[i]=i;num[i]=0;        }                for(i=1;i<=n;i++){            scanf("%s",s);            if(s[0]=='P'){                num1++;                scanf("%lf%lf%lf%lf",&x2[num1],&y2[num1],&x3[num1],&y3[num1]);                num[num1]=1;                for(j=1;j<=num1-1;j++){                    if(panduan(x2[j],y2[j],x3[j],y3[j],x2[num1],y2[num1],x3[num1],y3[num1])){                        t1=find(j);                        if(num1!=t1){                            pre[t1]=num1;num[num1]+=num[t1];                        }                        else continue;                    }                    //printf("%d ",panduan(x2[j],y2[j],x3[j],y3[j],x2[num1],y2[num1],x3[num1],y3[num1]));                }                //printf("\n");            }            else if(s[0]=='Q'){                scanf("%d",&a);                t1=find(a);                printf("%d\n",num[t1]);            }        }        if(h!=T)printf("\n");        /*for(i=1;i<=5;i++){            t1=find(i);            printf("%d ",num[t1]);        }        printf("\n");*/    }    return 0;}

0 0
原创粉丝点击