Segment Set
Time Limit: 3000/1000 MS (Java/others) memory limit: 32768/32768 K (Java/Others)
Total submission (s): 3486 accepted submission (s): 1297
Problem descriptiona 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.
Inputin 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.
Outputfor 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
12225
The intersection of a line segment is divided into two situations: 1. The line segment crosses each other, that is, they cross each other. 2. An endpoint of a line segment is located on another line segment.
Double Cross (point a, point B, point C) // cross product to determine the relationship between a point and a straight line position {// if the point is in the clockwise direction of a straight line, return a positive value return (B. x-a.x) * (C. y-a.y)-(C. x-a.x) * (B. y-a.y );}If the point is on a straight line (line segment or extended line), the return value is zero.
Bool ifin (point a, point B, point C) // judge whether the point is on the online segment {If (C. x> = min (. x, B. x) & C. y> = min (. y, B. y) & C. x <= max (. x, B. x) & C. Y <= max (. y, B. y) return true; return false ;}The following algorithm is used to determine whether a line segment is intersecting:
Bool judge (point a, point B, point C, point D) {// The experiment is rejected quickly, and 0 if (Cross (a, B, c) is not returned) = 0 & ifin (a, B, c) return true; else if (Cross (a, B, d) = 0 & ifin (A, B, d) return true; else if (Cross (c, d, A) = 0 & ifin (c, d, A) return true; else if (Cross (c, d, B) = 0 & ifin (c, d, B) return true; // cross-site experiment, the two ends of the line AB are at both ends of the CD, and the two ends of the line cd are at the two ends of the line AB. If (Cross (a, B, c) * Cross (a, B, d) <0 & cross (c, d, A) * Cross (c, d, B) <0) return true; return false ;}
Idea: each time you get a line segment to determine whether it is at the same time as all the previous lines, use and query the set operations to get the answer.
# Include "stdio. H "# include" string. H "# include" math. H "# include" vector "# include" iostream "# include" algorithm "using namespace STD; # define n 1005 const int INF = 0x7fffffff; int pre [N], num [N]; struct point {Double X, Y;}; struct node {Point P1, P2;} f [N]; double cross (point a, point B, point c) // cross product to determine the relationship between the point and the straight line position {// if the point is in the clockwise direction, return a positive value return (B. x-a.x) * (C. y-a.y)-(C. x-a.x) * (B. y-a.y);} bool ifin (point a, point B, point C) {If (C. X> = Min (. x, B. x) & C. y> = min (. y, B. y) & C. x <= max (. x, B. x) & C. Y <= max (. y, B. y) return true; return false;} bool judge (point a, point B, point C, point D) {// reject the experiment quickly, do not want to return 0 if (Cross (a, B, c) = 0 & ifin (a, B, c) return true; else if (Cross (A, B, C, d) = 0 & ifin (a, B, d) return true; else if (Cross (c, d, A) = 0 & ifin (C, d, a) return true; else if (Cross (c, d, B) = 0 & ifin (c, d, B) return true; // cross-site experiment. The two ends of line B are located at both ends of the CD, and the two ends of line B are located at the two ends of the line B. F (Cross (a, B, c) * Cross (a, B, d) <0 & cross (c, d, A) * Cross (c, d, B) <0) return true; return false;} int findx (int x) {If (X! = Pre [x]) Pre [x] = findx (pre [x]); return pre [X];} void unionset (int A, int B) {int F1, f2; F1 = findx (a); F2 = findx (B); If (F1! = F2) {pre [F1] = F2; num [F2] + = num [F1] ;}} int main () {int t, n, I, J, K, x; char ch; scanf ("% d", & T); While (t --) {scanf ("% d", & N); for (I = 1; I <= N; I ++) {pre [I] = I; num [I] = 1 ;}for (I = 1, j = 1; I <= N; I ++) {getchar (); scanf ("% C", & Ch); If (CH = 'q') {scanf ("% d ", & X); int xx = findx (x); printf ("% d \ n", num [XX]);} else {scanf ("% lf", & F [J]. p1.x, & F [J]. p1.y, & F [J]. p2.x, & F [J]. p2.y); For (k = 1; k <j; k ++) {If (Judge (F [K]. p1, F [K]. p2, F [J]. p1, F [J]. p2) unionset (K, J);} J ++;} If (t) puts ("") ;}return 0 ;}
HDU 1558 Segment Set (query set + calculation ry)