问题描述:
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
问题思路:
P命令插入一条线段。
Q命令查询线段K所在线段集合的线段数目。
套用了判断两条线段是否相交的模板。
代码:
#include<stdio.h> #include<algorithm> using namespace std; int pre[1007]; struct point { double x; double y; }; double mult(point a,point b,point c) { return (a.x-c.x)*(b.y-c.y)-(b.x-c.x)*(a.y-c.y); } bool check(point aa,point bb,point cc,point dd) { if(max(aa.x,bb.x)<min(cc.x,dd.x)) return false; if(max(aa.y,bb.y)<min(cc.y,dd.y)) return false; if (max(cc.x,dd.x)<min(aa.x,bb.x)) return false; if(max(cc.y,dd.y)<min(aa.y,bb.y)) return false; if(mult(cc,bb,aa)*mult(bb,dd,aa)<0) return false; if(mult(aa,dd,cc)*mult(dd,bb,cc)<0) return false; return true; } int find(int x) { int r=x; while(r!=pre[r]) r=pre[r]; int i=x,j; while(i!=r) { j=pre[i]; pre[i]=r; i=j; } return r; } void mix(int x,int y) { int fx=find(x); int fy=find(y); if(fx!=fy) pre[fy]=fx; } void compress(int x) { int r=x; while(r!=pre[r]) r=pre[r]; pre[x]=r; } int main() { int n,T,count_p; char c; struct point p1[1007]; struct point p2[1007]; while(scanf("%d",&T)!=EOF) { while(T--) { scanf("%d",&n); getchar(); count_p=0; for(int i=1;i<=n;i++) pre[i]=i; for(int i=1;i<=n;i++) { c=getchar(); if(c==‘P‘) { count_p++; scanf("%lf%lf%lf%lf",&p1[count_p].x,&p1[count_p].y,&p2[count_p].x,&p2[count_p].y); getchar(); for(int j=1;j<count_p;j++) if(check(p1[count_p],p2[count_p],p1[j],p2[j])) mix(count_p,j); } else{ int x; int count=0; scanf("%d",&x); getchar(); for(int i=1;i<=n;i++) compress(i); int root=find(x); for(int i=1;i<=n;i++) if(pre[i]==root) count++; printf("%d\n",count); } } if(T!=0) printf("\n"); } } return 0; }