I conduit!
Time Limit: 2000MS |
|
Memory Limit: 30000K |
Total Submissions: 1313 |
|
Accepted: 245 |
Description IRV Kenneth Diggit works for a company this excavates trenches, digs holes and generally tears up people ' s Yards. Irv ' s job is to make sure, that no underground pipe or cable are underneath where excavation is planned. He has several different maps, one for each utility company, showing where their conduits lie, and he needs to draw one LA RGE, consolidated map combining them all. One approach would is to simply draw each of the smaller maps one at a time onto the large map. However, this often wastes time, not to mention ink for the pen-plotter in the office, since in many cases portions of the Conduits overlap with all other (albeit at different depths underground). What Irv wants is a by-determine the minimum number of line segments-draw given all the line segments from the SEPA Rate maps.
Input input would consist of multiple Input sets. Each set would start with a single line containing a positive integer n indicating the total number of line segments from a ll the smaller maps. Each of the next n lines would contain a description of one segment in the format
X1 y1 X2 y2
where (x1,y1) is the coordinates of one endpoint and (x2,y2) is the coordinates of the other. Coordinate values is floating point values in the range 0...1000 Speci.ed to at most of the decimal places. The maximum number of line segments is 10000 and all segments would have non-zero length. Following the last input set there is a line containing a 0 indicating end of input; It should not being processed.
Output for each input set, output on a single line the minimum number of line segments this need to being drawn on the larger , consolidated map.
Sample Input
3
1.0 10.0 3.0 14.0
0.0 0.0 20.0 20.0
10.0 28.0 2.0 12.0
2
0.0 0.0 1.0 1.0
1.0 1.0 2.15 2.15
2
0.0 0.0 1.0 1.0
1.0 1.0 2.15 2.16
0
Sample Output
2
1
2
Source East Central North America 2004
/* Oh, this is the top 20 6262545 bobten2008 732K 141MS C + + 2246B 2009-12-20 14:52:15 very disgusting computational geometry, the core idea is to sort the seg according to the slope by sort, where there are four points in the wrong place 1 ) accuracy problem, need to add EPS correction. 2) The order of the two points of each seg in the input data is either left-to-right or bottom-to-top, so you need to adjust the two endpoints of the SEG, such as 1 2 3 2 for the line, and possibly in the form of 3 2 1 2, where I uniformly tune from bottom to top, left to right, If not adjusted here, the subsequent work may be affected. 3) Sorting algorithm comparison function, more complex, need to consider the vertical line (that is, no slope), see note 4 in the body of the final sequence after scanning the sorted seg, you need to adjust the current seg x2 or Y2 value, for example, [1 2 10 2], [2 2 5 2] [6 2 12] This set of data, sort The second SEG is included in the first SEG, and if the Y2 coordinate of the second SEG is not fixed, then the third seg is definitely not included when dealing with the third SEG, so the final answer is 2, In fact, the answer to this set of data should be 1. Therefore, after processing the second SEG, it is necessary to revise its y2 to 10. How to fix it, very simple, as long as the y2 for the current seg y2 and the y2 of the previous SEG maximum can be the time complexity of the algorithm is O (NLGN) */#include <iostream> #include <algorithm> #include <cmath> #define EPS 1e-8 #define MAX_N 10005 using namespace St D struct SEG {Double x1, y1, x2, y2; bool spe;//spe = True indicates that the current SEG is parallel to the y-axis, otherwise it is not parallel, and the y-axis is not slope when double A, b; Segs[max_n]; int n; Comparison function, the core idea is to put no slope (and the y-axis parallel) on the back of the slope, the slope is small in front of the slope large//For the same slope of the SEG, the intersection with the y-axis low in front//for the SEG on a line, the x-coordinate (when parallel to the y-axis of the Y Small put in front bool compare (const SEG &SEG1, const SEG &SEG2) {Two seg have no slope if (Seg1.spe && Seg2.spe) return Fabs (seg1.x1-seg2.x1) < EPS? Seg1.y1 < Seg2.y1 + EPS:seg1.x1 < seg2.x2 + EPS; else if (Seg1.spe &&!seg2.spe) return false; One has a slope with no slope, put the slope in front of the else if (!seg1.spe && Seg2.spe) return true; else//Two SEG has a slope {//slope equal to the intersection with the y-axis, when the focus is also equal, you need to compare the size of the left endpoint x value if (Fabs (seg1.a-seg2.a) < EPS) return Fabs (seg1.b-seg2.b) & Lt Eps? Seg1.x1 < seg2.x1 + eps:seg1.b < seg2.b + EPS; else return seg1.a < seg2.a + EPS; }} void swap (double &d1, double &d2) {Double temp = d1; d1 = d2; d2 = temp;}//Determine if two seg intersect, type is used to distinguish the two seg from the y-axis Parallel condition, type = 0 when represented with y-axis parallel bool Cross (const seg& SEG1, const SEG &SEG2, BOOL type) {if (!type) return seg2.y1 <= seg 1.y2; else return seg2.x1 <= seg1.x2; } int main () {int i; while (scanf ("%d", &n) && n! = 0) {for (i = 0; i < n; i++) {scanf ("%lf%lf%lf%lf", &am P;segs[i].x1, &segs[i].y1, &segs[i].x2, &segs[i].y2); if (Segs[i].x1 > segs[i].x2 + EPS) {swap (segs[i].x1, segs[i].x2), swap (Segs[i].y1, segs[i].y2),} else if (Fabs (SEGS[I].X1-SEGS[I].X2) < EPS &am p;& segs[i].y1 > Segs[i].y2 + EPS) {swap (segs[i].x1, segs[i].x2); Swap (segs[i].y1, segs[i].y2);} Segs[i].spe = FA Lse if (Fabs (SEGS[I].X1-SEGS[I].X2) < EPS) Segs[i].spe = true; else {segs[i].a = (segs[i].y2-segs[i].y1)/(segs[i].x2-segs[i].x1); segs[i].b = segs[i].y1-segs[i].x1 * SEGS[I].A; }} sort (Segs, Segs + N, compare); int COUNTV = 1; for (i = 1; i < n; i++) {//The current SEG is parallel to the y-axis as it intersects the previous SEG if (Segs[i].spe && segs[i-1].spe && fabs (segs[i].x1- SEGS[I-1].X1) < EPS && Cross (Segs[i-1], segs[i], false)) {//adjust y2 if for current seg (Segs[i].y2 < Segs[i-1].y2 + EPS) segs[i].y2 = Segs[i-1].y2; Continue }//The current SEG is not parallel to the y-axis and intersects with the previous SEG if (!segs[i].spe &&!segs[i-1].spe && fabs (SEGS[I].A-SEGS[I-1].A) < EPS && fabs (segs[i].b-segs[i-1].b) < EPS && Cross (Segs[i-1], segs[i], True)) {//TuneEntire Current seg X2 if (segs[i].x2 < segs[i-1].x2 + EPS) segs[i].x2 = segs[i-1].x2; Continue }//Find a new SEG that is not merged with the previous SEG, you need to increase the value of COUNTV by 1 countv++; } printf ("%d/n", COUNTV); } return 0; }