线段判交模板
整理一下模板、才发现原来的写法是错的、郁闷。
HDU 1086
You can Solve a Geometry Problem too
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 7893 Accepted Submission(s): 3853
Problem Description
Many geometry(几何)problems were designed in the ACM/ICPC. And now, I also prepare a geometry problem for this final exam. According to the experience of many ACMers, geometry problems are always much trouble, but this problem is very easy, after all we are now attending an exam, not a contest :) Give you N (1<=N<=100) segments(线段), please output the number of all intersections(交点). You should count repeatedly if M (M>2) segments intersect at the same point.
Note: You can assume that two segments would not intersect at more than one point.
Note: You can assume that two segments would not intersect at more than one point.
Input
Input contains multiple test cases. Each test case contains a integer N (1=N<=100) in a line first, and then N lines follow. Each line describes one segment with four float values x1, y1, x2, y2 which are coordinates of the segment’s ending. A test case starting with 0 terminates the input and this test case is not to be processed.
Output
For each case, print the number of intersections, and one line one case.
Sample Input
2 0.00 0.00 1.00 1.00 0.00 1.00 1.00 0.00 3 0.00 0.00 1.00 1.00 0.00 1.00 1.00 0.000 0.00 0.00 1.00 0.00 0
Sample Output
1 3
#include <iostream> #include <cstdio> #include <cmath> #include <cstring> using namespace std; #define EPS 1e-8 #define PI acos(-1.0) int dump(double x) { if(fabs(x)<EPS) return 0; return x<0?-1:1; } struct Point { double x,y; Point (){} Point (double x,double y):x(x),y(y){} Point operator + (const Point &p)const { return Point(x+p.x,y+p.y); } Point operator - (const Point &p)const { return Point(x-p.x,y-p.y); } double operator ^ (const Point &p)const { return x*p.y-y*p.x; } double operator * (const Point &p)const { return x*p.x+y*p.y; } }; struct Line { Point s,e; Line (){} Line (Point s,Point e):s(s),e(e){} }; bool SegInterSeg(Line l1,Line l2) { return max(l1.s.x,l1.e.x)>=min(l2.s.x,l2.e.x) && max(l2.s.x,l2.e.x)>=min(l1.s.x,l1.e.x) && max(l1.s.y,l1.e.y)>=min(l2.s.y,l2.e.y) && max(l2.s.y,l2.e.y)>=min(l1.s.y,l1.e.y) && dump((l2.s-l1.e)^(l1.s-l1.e))*dump((l2.e-l1.e)^(l1.s-l1.e))<=0 && dump((l1.s-l2.e)^(l2.s-l2.e))*dump((l1.e-l2.e)^(l2.s-l2.e))<=0; } int main() { int i,j,n; Line l[1010]; while(scanf("%d",&n),n) { for(i=1;i<=n;i++) { scanf("%lf%lf%lf%lf",&l[i].s.x,&l[i].s.y,&l[i].e.x,&l[i].e.y); } int cnt=0; for(i=1;i<=n;i++) { for(j=i+1;j<=n;j++) { if(SegInterSeg(l[i],l[j])) cnt++; } } cout<<cnt<<endl; } return 0; }
HDU 1147
Pick-up sticks
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 2172 Accepted Submission(s): 800
Problem Description
Stan has n sticks of various length. He throws them one at a time on the floor in a random way. After finishing throwing, Stan tries to find the top sticks, that is these sticks such that there is no stick on top of them. Stan has noticed that the last thrown stick is always on top but he wants to know all the sticks that are on top. Stan sticks are very, very thin such that their thickness can be neglected. ![](http://acm.hdu.edu.cn/data/images/1147-1.jpg)
![](http://acm.hdu.edu.cn/data/images/1147-1.jpg)
Input
Input consists of a number of cases. The data for each case start with 1 ≤ n ≤ 100000, the number of sticks for this case. The following n lines contain four numbers each, these numbers are the planar coordinates of the endpoints of one stick. The sticks are listed in the order in which Stan has thrown them. You may assume that there are no more than 1000 top sticks. The input is ended by the case with n=0. This case should not be processed.
Output
For each input case, print one line of output listing the top sticks in the format given in the sample. The top sticks should be listed in order in which they were thrown. The picture to the right below illustrates the first case from input.
Sample Input
5 1 1 4 2 2 3 3 1 1 -2.0 8 4 1 4 8 2 3 3 6 -2.0 3 0 0 1 1 1 0 2 1 2 0 3 1 0
Sample Output
Top sticks: 2, 4, 5. Top sticks: 1, 2, 3.
#include <iostream> #include <cstdio> #include <cmath> #include <cstring> using namespace std; #define EPS 1e-8 #define N 100010 int dump(double x) { if(fabs(x)<EPS) return 0; return x<0?-1:1; } struct Point { double x,y; Point (){} Point (double x,double y):x(x),y(y){} Point operator + (const Point &p)const { return Point(x+p.x,y+p.y); } Point operator - (const Point &p)const { return Point(x-p.x,y-p.y); } double operator ^ (const Point &p)const { return x*p.y-y*p.x; } double operator * (const Point &p)const { return x*p.x+y*p.y; } }; struct Line { Point s,e; Line (){} Line (Point s,Point e):s(s),e(e){} }; bool SegInterSeg(Line l1,Line l2) { return max(l1.s.x,l1.e.x)>=min(l2.s.x,l2.e.x) && max(l2.s.x,l2.e.x)>=min(l1.s.x,l1.e.x) && max(l1.s.y,l1.e.y)>=min(l2.s.y,l2.e.y) && max(l2.s.y,l2.e.y)>=min(l1.s.y,l1.e.y) && dump((l2.s-l1.e)^(l1.s-l1.e))*dump((l2.e-l1.e)^(l1.s-l1.e))<=0 && dump((l1.s-l2.e)^(l2.s-l2.e))*dump((l1.e-l2.e)^(l2.s-l2.e))<=0; } int n,m; Line l[N]; int vis[N]; int main() { int i,j; while(scanf("%d",&n),n) { memset(vis,1,sizeof(vis)); for(i=1;i<=n;i++) { scanf("%lf%lf%lf%lf",&l[i].s.x,&l[i].s.y,&l[i].e.x,&l[i].e.y); } for(i=1;i<=n;i++) { for(j=i+1;j<=n;j++) { if(SegInterSeg(l[i],l[j])) { vis[i]=0; break; } } } printf("Top sticks: "); bool first=1; for(i=1;i<=n;i++) { if(vis[i]) { if(first) { first=0; cout<<i; } else cout<<", "<<i; } } cout<<'.'<<endl; } return 0; }
HDU 1558
Segment set
Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3564 Accepted Submission(s): 1328
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.![](http://acm.hdu.edu.cn/data/images/C50-1004-1.jpg)
![](http://acm.hdu.edu.cn/data/images/C50-1004-1.jpg)
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.
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
#include <iostream> #include <cstdio> #include <cmath> #include <cstring> using namespace std; #define EPS 1e-8 #define N 1010 int dump(double x) { if(fabs(x)<EPS) return 0; return x<0?-1:1; } struct Point { double x,y; Point (){} Point (double x,double y):x(x),y(y){} Point operator + (const Point &p)const { return Point(x+p.x,y+p.y); } Point operator - (const Point &p)const { return Point(x-p.x,y-p.y); } double operator ^ (const Point &p)const { return x*p.y-y*p.x; } double operator * (const Point &p)const { return x*p.x+y*p.y; } }; struct Line { Point s,e; Line (){} Line (Point s,Point e):s(s),e(e){} }; bool SegInterSeg(Line l1,Line l2) { return max(l1.s.x,l1.e.x)>=min(l2.s.x,l2.e.x) && max(l2.s.x,l2.e.x)>=min(l1.s.x,l1.e.x) && max(l1.s.y,l1.e.y)>=min(l2.s.y,l2.e.y) && max(l2.s.y,l2.e.y)>=min(l1.s.y,l1.e.y) && dump((l2.s-l1.e)^(l1.s-l1.e))*dump((l2.e-l1.e)^(l1.s-l1.e))<=0 && dump((l1.s-l2.e)^(l2.s-l2.e))*dump((l1.e-l2.e)^(l2.s-l2.e))<=0; } int n,m; int f[N]; Line l[N]; int sum[N]; int Find(int x) { return x==f[x]?x:Find(f[x]); } void un(int x,int y) { x=Find(x); y=Find(y); if(x>y) f[x]=y,sum[y]+=sum[x]; if(x<y) f[y]=x,sum[x]+=sum[y]; } int main() { int T,i,iCase=1; scanf("%d",&T); while(T--) { n=0; for(i=1;i<=1000;i++) { f[i]=i; sum[i]=1; } if(iCase!=1) printf("\n"); iCase++; scanf("%d",&m); while(m--) { char op; scanf(" %c",&op); if(op=='P') { n++; scanf("%lf%lf%lf%lf",&l[n].s.x,&l[n].s.y,&l[n].e.x,&l[n].e.y); for(i=1;i<n;i++) { if(SegInterSeg(l[n],l[i])) { un(n,i); } } } else { int x; scanf("%d",&x); x=Find(x); printf("%d\n",sum[x]); } } } return 0; }
趁着还有梦想、将AC进行到底~~~by 452181625