topcoder算法练习3
SRM144 DIV1 1100 point
Problem Statement |
|||||||||||||
NOTE: There are images in the examples section of this problem statement that help describe the problem. Please view the problem statement in the HTML window to view them. Given a picture composed entirely of horizontal and vertical line segments, calculate the minimum number of times you must lift your pen to trace every line segment in the picture exactly n times. Each line segment will be of the form "<x1> <y1> <x2> <y2>" (quotes for clarity), representing a segment from (x1,y1) to (x2,y2). Segments may cross each other. Segments may also overlap, in which case you should count the overlapping region as appearing in the drawing only once. For example, say the drawing were composed of two lines: one from (6,4) to (9,4), and one from (8,4) to (14,4). Even though they overlap from (8,4) to (9,4), you should treat the drawing as if it were a single line from (6,4) to (14,4). You would not need to lift your pen at all to trace this drawing. |
|||||||||||||
Definition |
|||||||||||||
|
|||||||||||||
Notes |
|||||||||||||
- | The pen starts on the paper at a location of your choice. This initial placement does not count toward the number of times that the pen needs to be lifted. | ||||||||||||
Constraints |
|||||||||||||
- | segments will contain between 1 and 50 elements, inclusive. | ||||||||||||
- | Each element of segments will contain between 7 and 50 characters, inclusive. | ||||||||||||
- | Each element of segments will be in the format "<X1>_<Y1>_<X2>_<Y2>" (quotes for clarity). The underscore character represents exactly one space. The string will have no leading or trailing spaces. | ||||||||||||
- | <X1>, <Y1>, <X2>, and <Y2> will each be between -1000000 and 1000000, inclusive, with no unnecessary leading zeroes. | ||||||||||||
- | Each element of segments will represent a horizontal or vertical line segment. No line segment will reduce to a point. | ||||||||||||
- | n will be between 1 and 1000000, inclusive. | ||||||||||||
Examples |
|||||||||||||
0) | |||||||||||||
|
|||||||||||||
1) | |||||||||||||
|
|||||||||||||
2) | |||||||||||||
|
|||||||||||||
3) | |||||||||||||
|
|||||||||||||
4) | |||||||||||||
|
|||||||||||||
5) | |||||||||||||
|
This problem statement is the exclusive and proprietary property of TopCoder, Inc. Any unauthorized use or reproduction of this information without the prior written consent of TopCoder, Inc. is strictly prohibited. (c)2003, TopCoder, Inc. All rights reserved.
这道题思路不难,但是还是感觉实现起来好费劲
思路是这样的
step1 将字符串数组编程数字线段列表
step2 去掉overlap的得到不重叠的线段组
step3 找交叉点,包括端点 记录每个点的交叉的出度 再乘以n
step4 一对奇数出度点代表 抬笔一次
这个程序太复杂,根本没写完,自己太挫了,觉得算overlap好麻烦啊
1 #include <vector> 2 #include <list> 3 #include <string> 4 #include <stdlib.h> 5 #include <stdint.h> 6 #include <stdio.h> 7 8 using namespace std; 9 10 class PenLift{ 11 public: 12 int numTimes(vector <string>, int); 13 }; 14 int PenLift::numTimes(vector <string> segments, int n){ 15 //turn string segment vector to int segment vector 16 int penlift = 0; 17 int segnum = segments.size(); 18 list<int*> seglist; 19 int i,j,k; 20 int start,space; 21 string sseg; 22 string snum; // string for single number 23 string::iterator iter; 24 for(i=0;i<segnum;i++){ 25 start=0; 26 space=0; 27 sseg=segments.at(i); 28 j=0; 29 k=0; 30 int nseg[4]; 31 for(iter=sseg.begin();iter!=sseg.end();iter++){ 32 if(*iter==' '){ 33 space = j; 34 snum=sseg.substr(start,space-start); 35 nseg[k]=atoi(snum.c_str()); 36 start = space+1; 37 k++; 38 } 39 j++; 40 } 41 snum=sseg.substr(start,j-start); 42 snum=sseg.substr(start,space-start); 43 nseg[k]=atoi(snum.c_str()); 44 seglist.push_back(nseg); 45 } 46 //reduce overlap 47 list<int*>::iterator iteri,iterj,itert; 48 for(iteri=seglist.begin();iteri!=seglist.end();iteri++){ 49 for(iterj=iteri++;iterj!=seglist.end();iterj++){ 50 if((int*)(*iteri)[0]==(int*)(*iterj)[0]){ 51 if(iterj[1]<=iterj[3]){ 52 if(iteri[1]>=iterj[1]&&iteri[1]<=iterj[3]){ 53 if(iteri[3]>=iterj[1]&&iteri[3]<=iterj[3]){ 54 55 }else if( ){} 56 } 57 }else{ 58 59 } 60 } 61 } 62 } 63 return penlift; 64 }