hdu_1086 You can Solve a Geometry Problem too

题意:给定n条线段(n≤100),求有多少个交点(若有多于两条线段交于一点,应重复计数(即可以视为任意两条线段不交于同一点))。

题解:判定线段相交的裸题。只需要枚举任意两条线段是否相交即可。(方法为判断线段AB的端点A,B是否在线段CD两侧,且C,D在线段AB两侧。注意特判一个端点在另一条线段上的情况。)

代码:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstdlib>
 4 #include<cstring>
 5 #include<algorithm>
 6 #include<cmath>
 7 #define eps 1e-15
 8 using namespace std;
 9 int n,t,ans;
10 struct vec{
11     double x,y;
12 };
13 struct node{
14     vec a,b;
15 }e[110];
16 double che(vec a,vec b){
17     return a.x*b.y-a.y*b.x;
18 }
19 double ab(vec a){
20     return a.x*a.x+a.y*a.y;
21 }
22 vec miu(vec a,vec b){
23     return (vec){a.x-b.x,a.y-b.y};
24 }
25 bool on(node a,node b){
26     double x=ab(miu(b.a,a.a)),y=ab(miu(a.b,b.a)),z=ab(miu(a.b,a.a));
27     if(x+y==z)  return true;
28     x=ab(miu(b.b,a.a));y=ab(miu(a.b,b.b));
29     if(x+y==z)  return true;
30     return false;
31 }
32 bool pan(node a,node b){
33     vec aa=miu(a.b,a.a);
34     double x=che(miu(a.b,a.a),miu(b.a,a.a))*che(miu(a.b,a.a),miu(b.b,a.a));
35     double y=che(miu(b.b,b.a),miu(a.a,b.a))*che(miu(b.b,b.a),miu(a.b,b.a));
36     if(x<0 && y<0)  return true;
37     if(on(a,b))  return true;
38     return false;
39 }
40 int main(){
41     int i,j,k,l;
42     scanf("%d",&n);
43     while(n!=0){
44         ans=0;memset(e,0,sizeof(e));
45         for(i=1;i<=n;++i){
46             scanf("%lf%lf%lf%lf",&e[i].a.x,&e[i].a.y,&e[i].b.x,&e[i].b.y);
47             for(j=1;j<i;++j){
48                 if(pan(e[j],e[i]))  ans++;
49             }
50         }
51         printf("%d\n",ans);
52         scanf("%d",&n);
53     }
54     return 0;
55 }
View Code

 

posted @ 2017-12-18 16:15  lazytear  阅读(144)  评论(0编辑  收藏  举报