【kuangbin专题】计算几何基础(直线,线段相交)

 

 


 

【POJ 2318】 TOYS

 

【题目大意】

给定 n 条直线,m个玩具,每两个直线之间是一个隔间,一个玩具有一个坐标,问一个隔间内有多少个玩具

 

【题目思路】

暴力枚举,每读入一个点,扫一遍所有边,判断这个点是不是在两边之间,如果在,就给当前边的答案

1 bool is_midd(P a, L b, L c)
2 {//分别求点a 和 b,c的叉乘,判断他是在直线的左边还是右边
//如果两者异号,,则说明两边分别在点的不同方向
3 int x = cmp(cross(a - b.s, b.t - b.s)),
y = cmp(cross(a - c.s, c.t - c.s)); 4 return x * y <= 0; 5 6 }

 

【代码】

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<vector>
  4 #include<queue>
  5 #include<iostream>
  6 #include<algorithm>
  7 #include<cmath>
  8 using namespace std;
  9 const double eps = 1e-6;
 10 const int    MAXN = 20010;
 11 const double lim = 10000;
 12 const double PI = acos(-1.0);
 13 int n, m;
 14 inline int cmp(double x)
 15 {
 16     if (x > eps)return 1;
 17     return x < -eps ? -1 : 0;
 18 }
 19 struct V
 20 {
 21     int x, y;
 22     double ang;
 23     double angle()
 24     {//求取极角
 25         return atan2(y, x);
 26     }
 27     V(int X = 0,int Y = 0)
 28     {
 29         //初始化
 30         x = X, y = Y;
 31     }
 32     bool operator ==(const V &b)
 33     {
 34         return cmp(x - b.x) && cmp(y - b.y);
 35     }
 36 
 37 };
 38 typedef V  P;
 39 V operator +(V a, V b) { return V(a.x + b.x, a.y + b.y); }
 40 V operator -(V a, V b) { return V(a.x - b.x, a.y - b.y); }
 41 V operator *(V a, double b) { return V(a.x *b, a.y*b); }
 42 V operator /(V a, double b) { return V(a.x / b, a.y / b); }
 43 struct L
 44 {
 45     P s, t;
 46     double ang;
 47     L(P X = V(), P Y = V())
 48     {
 49         s = X, t = Y; 
 50     }
 51 };
 52 typedef L S;
 53 double cross(V a, V b)
 54 {
 55     return 1.0*a.x*b.y - 1.0*a.y*b.x;
 56 }
 57 bool is_midd(P a, L b, L c)
 58 {
 59     int x = cmp(cross(a - b.s, b.t - b.s)), y = cmp(cross(a - c.s, c.t - c.s));
 60     return x * y <= 0;
 61 
 62 }
 63 P p[MAXN];
 64 L l[MAXN];
 65 int ans[MAXN];
 66 int main()
 67 {
 68     int n, m, x1, y1, x2, y2;
 69     while (scanf("%d", &n))
 70     {
 71         if (n == 0)
 72             break;
 73         scanf("%d%d%d%d%d", &m, &x1, &y1, &x2, &y2);
 74         l[0].s = P(x1, y2), l[0].t = P(x1, y1);
 75         l[n + 1].s = P(x2, y2), l[n + 1].t = P(x2, y1);
 76         for (int i = 1; i <= n; i++)
 77         {
 78             int u, v;
 79             scanf("%d%d", &u, &v);
 80             l[i].s = P(v, y2), l[i].t = P(u, y1);
 81         }
 82         memset(ans, 0, sizeof(ans));
 83         int temp = 0;
 84         for (int i = 1; i <= m; i++)
 85         {
 86             int x, y;
 87             scanf("%d%d", &x, &y);
 88             P tmp = P(x, y);
 89             for (int j = 0; j <= n; j++)
 90             {
 91                 if (is_midd(tmp,l[j],l[j+1]))
 92                 {
 93                     
 94                     ans[j]++;
 95                     break;
 96                 }
 97             }
 98         }
 99         for (int i = 0; i <= n; i++)
100             printf("%d: %d\n", i, ans[i]);
101         printf("\n");
102     }
103     return 0;
104 }
View Code

 


 

【POJ  3304】Segments

【题目大意】

给定 n 条线段,判断是否存在一个线段使他们投影在那条线端上的投影有交点,有输出“Yes”,无输出“No”

【题目分析】

 思考下对于这个几何问题,投影的话可以看作从一条直线上对要投影的直线进行投影

所以,对投影区域的直线做一条垂直的直线,而这条直线就能够和所有直线相交,所以问题可以简化为

(以上说明变成几何形状放在脑子里面思考一下)

 

是否存在一条直线,能够和给定的所有直线相交

一条直线能够和所有直线相交的情况,最极端的看作,如果这条直线和线段端点有交点,则可以进行缩减

如果没有,因为已经到了端点,继续转必然导致无法相交

所以只需要判断各个直线的端点即可


double cross(V a, V b)
{
	return a.x*b.y - a.y*b.x;
}
double cross(P a, P b, P c)
{
	
	return cross(b-a, c-a);
}
bool L_is_Inter(L a, L b)
{
  //分别判断线段 b的起始点和终止点在 线段 a 的左侧还是右侧
//如果在不同侧的话,就说明两个线段相交
return cmp(cross(b.s, a.s, a.t))*cmp(cross(b.t, a.s, a.t)) <= 0; } 

【代码】

 

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<vector>
  4 #include<queue>
  5 #include<iostream>
  6 #include<algorithm>
  7 #include<cmath>
  8 #define cmp sgn
  9 using namespace std;
 10 const double eps = 1e-8;
 11 const int    MAXN = 110;
 12 const double lim = 10000;
 13 const double PI = acos(-1.0);
 14 int n, m;
 15 inline int sgn(double x)
 16 {
 17     if (x > eps)return 1;
 18     return x < -eps ? -1 : 0;
 19 }
 20 struct V
 21 {
 22     double x, y;
 23     double ang;
 24     double angle()
 25     {//求取极角
 26         return atan2(y, x);
 27     }
 28     V(double X = 0, double Y = 0)
 29     {
 30         //初始化
 31         x = X, y = Y;
 32         ang = atan2(y, x);
 33     }
 34     bool operator ==(const V &b)
 35     {
 36         return cmp(x - b.x) && cmp(y - b.y);
 37     }
 38 
 39 };
 40 typedef V  P;
 41 V operator +(V a, V b) { return V(a.x + b.x, a.y + b.y); }
 42 V operator -(V a, V b) { return V(a.x - b.x, a.y - b.y); }
 43 V operator *(V a, double b) { return V(a.x *b, a.y*b); }
 44 double operator *(V a, V b) { return a.x*b.x+a.y*b.y; }
 45 V operator /(V a, double b) { return V(a.x / b, a.y / b); }
 46 struct L
 47 {
 48     P s, t;
 49     double ang;
 50     L(P X = V(), P Y = V())
 51     {
 52         s = X, t = Y, ang = (Y - X).angle();
 53     }
 54 };
 55 typedef L S;
 56 double cross(V a, V b)
 57 {
 58     return a.x*b.y - a.y*b.x;
 59 }
 60 double cross(P a, P b, P c)
 61 {
 62     
 63     return cross(b-a, c-a);
 64 }
 65 bool L_is_Inter(L a, L b)
 66 {
 67     return cmp(cross(b.s, a.s, a.t))*cmp(cross(b.t, a.s, a.t)) <= 0;
 68 }
 69 P p[MAXN];
 70 L l[MAXN];
 71 
 72 bool check(P b,P c)
 73 {
 74     L a = L(b, c);
 75     if (sgn(dis(a.s, a.t)) == 0)return false;
 76     for(int i=1;i<=n;i++)
 77         if (!L_is_Inter(a, l[i]))
 78         {
 79             return false;
 80         }
 81     return true;
 82 }
 83 int main()
 84 {
 85     int T;
 86     scanf("%d", &T);
 87     while (T--)
 88     {
 89         bool flag = false;
 90         scanf("%d", &n);
 91         for (int i = 1; i <= n; i++)
 92         {
 93             scanf("%lf%lf%lf%lf", &l[i].s.x, &l[i].s.y,&l[i].t.x,&l[i].t.y);
 94         }
 95         for(int i=1;i<=n;i++)
 96             for (int j = 1; j <= n; j++)
 97             {
 98                 if (check(l[i].s, l[j].s) || check(l[i].s, l[j].t) || check(l[i].t, l[j].t) || check(l[i].t, l[j].s))
 99                 {
100                     flag = true;
101                     break;
102                 }
103                 if (flag)
104                     break;
105             }
106         if (flag)
107             printf("Yes!\n");
108         else
109             printf("No!\n");
110     }
111     return 0;
112 }
View Code

 


 

【POJ  1269】Intersecting Lines

【题目大意】

 给定n组线段,每组有两个线段,判断他们是否相交,如果相交输出交点,没有输出“NONE”,重合输出 “LINE”

【题目分析】

计算几何基础知识裸题,考察计算几何知识

 

 

【代码】

 

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<vector>
  4 #include<queue>
  5 #include<iostream>
  6 #include<algorithm>
  7 #include<cmath>
  8 using namespace std;
  9 const double eps = 1e-6;
 10 const int    MAXN = 20010;
 11 const double lim = 10000;
 12 const double PI = acos(-1.0);
 13 int n, m;
 14 inline int cmp(double x)
 15 {
 16     if (x > eps)return 1;
 17     return x < -eps ? -1 : 0;
 18 }
 19 struct V
 20 {
 21     double x, y;
 22     double ang;
 23     double angle()
 24     {//求取极角
 25         return atan2(y, x);
 26     }
 27     V(double X = 0, double Y = 0)
 28     {
 29         //初始化
 30         x = X, y = Y;
 31         ang = atan2(y, x);
 32     }
 33     bool operator ==(const V &b)
 34     {
 35         return cmp(x - b.x) && cmp(y - b.y);
 36     }
 37 
 38 };
 39 typedef V  P;
 40 V operator +(V a, V b) { return V(a.x + b.x, a.y + b.y); }
 41 V operator -(V a, V b) { return V(a.x - b.x, a.y - b.y); }
 42 V operator *(V a, double b) { return V(a.x *b, a.y*b); }
 43 V operator /(V a, double b) { return V(a.x / b, a.y / b); }
 44 struct L
 45 {
 46     P s, t;
 47     double ang;
 48     L(P X = V(), P Y = V())
 49     {
 50         s = X, t = Y, ang = (Y - X).angle();
 51     }
 52 };
 53 typedef L S;
 54 double cross(V a, V b)
 55 {
 56     return a.x*b.y - a.y*b.x;
 57 }
 58 
 59 double dot(V a, V b)
 60 {
 61     return a.x*b.x + a.y*b.y;
 62 }
 63 bool is_parallel(L a, L b)
 64 {
 65     return cmp(cross(a.t - a.s, b.t - b.s)) == 0;
 66 }
 67 double cross(P a, P b, P c)
 68 {
 69 
 70     return cross(b - a, c - a);
 71 }
 72 bool L_is_Inter(L a, L b)
 73 {
 74     //分别判断线段 b的起始点和终止点在 线段 a 的左侧还是右侧
 75      //如果在不同侧的话,就说明两个线段相交 
 76     //return cmp(cross(b.s, a.s, a.t))*cmp(cross(b.t, a.s, a.t)) <= 0;
 77     return cmp(cross(b.s, b.t, a.s))==0;
 78 }
 79 P intersection(L a, L b)
 80 {
 81     return a.s + (a.t - a.s)*(cross(b.t - b.s, a.s - b.s)) / cross(a.t - a.s, b.t - b.s);
 82 }
 83 P p[MAXN];
 84 L l[MAXN];
 85 int main()
 86 {
 87     int n;
 88     scanf("%d", &n);
 89     printf("INTERSECTING LINES OUTPUT\n");
 90     for (int i = 1; i <= n; i++)
 91     {
 92         L a, b;
 93         scanf("%lf %lf %lf %lf %lf %lf %lf %lf", &a.s.x, &a.s.y, &a.t.x, &a.t.y, &b.s.x, &b.s.y, &b.t.x, &b.t.y);
 94         if (is_parallel(a, b))
 95         {
 96             if (L_is_Inter(a, b))
 97                 printf("LINE\n");
 98             else
 99                 printf("NONE\n");
100         }
101         else
102         {
103         
104                 P p = intersection(a, b);
105                 printf("POINT %.2f %.2f\n", p.x, p.y);
106         
107             
108         }
109     }
110     printf("END OF OUTPUT\n");
111     return 0;
112 }
View Code

 


 

【POJ 1556】The Doors

【题目大意】

给定一个正方形和里面的墙,求从点(0,5)到点(10,5)的最短路径

【题目分析】

枚举所有点两两之间的点,当两个点之间没有墙壁挡着,即没有和墙相交的情况下,说明这两个点可以互相到达,记录

处理完所有可以走的点之间的路径之后

因为最多只有18堵墙,所以直接一波Floyd求最短路径

就能够得到我们所想要的答案

【代码】

 

  1 #include<cstdio>
  2 #include<cmath>
  3 #include<iostream>
  4 #include<algorithm>
  5 #define sgn cmp
  6 #define e t
  7 #define ll long long
  8 using namespace std;
  9 const int MAXN = 5010;
 10 const double eps = 1e-9;
 11 const double INF = 1e5;
 12 inline int cmp(double x)
 13 {
 14     if (x > eps)return 1;
 15     return x < -eps ? -1 : 0;
 16 }
 17 struct P
 18 {
 19     double x, y;
 20     P(double a = 0, double b = 0) :x(a), y(b) {}
 21     double operator ^(const P &b)const
 22     {
 23         return x * b.y - y * b.x;
 24     }
 25 };
 26 
 27 struct L
 28 {
 29     P s, t;
 30     L(P      a = P(0, 0), P      b = P(0, 0)) :s(a), t(b) {}
 31 };
 32 typedef P  V;
 33 bool operator ==(V a, V b) { return (cmp(a.x - b.x) == 0) && (cmp(a.y - b.y)); }
 34 V operator +(V a, V b) { return V(a.x + b.x, a.y + b.y); }
 35 V operator -(V a, V b) { return V(a.x - b.x, a.y - b.y); }
 36 V operator *(V a, double b) { return V(a.x *b, a.y*b); }
 37 double operator *(V a, V b) { return a.x*b.x + a.y*b.y; }
 38 V operator /(V a, double b) { return V(a.x / b, a.y / b); }
 39 double dis(P a, P b)
 40 {
 41     P tmp = b - a;
 42     return sqrt(tmp * tmp);
 43 }
 44 double cross(V a, V b)
 45 {
 46     return a.x*b.y - a.y*b.x;
 47 }
 48 double cross(P a, P b, P c)
 49 {
 50 
 51     return cross(b - a, c - a);
 52 }
 53 bool L_is_Inter(L l1, L l2)
 54 {
 55     return
 56         max(l1.s.x, l1.e.x) >= min(l2.s.x, l2.e.x) &&
 57         max(l2.s.x, l2.e.x) >= min(l1.s.x, l1.e.x) &&
 58         max(l1.s.y, l1.e.y) >= min(l2.s.y, l2.e.y) &&
 59         max(l2.s.y, l2.e.y) >= min(l1.s.y, l1.e.y) &&
 60         sgn((l2.s - l1.s) ^ (l1.e - l1.s))*sgn((l2.e - l1.s) ^ (l1.e - l1.s)) < 0 &&
 61         sgn((l1.s - l2.s) ^ (l2.e - l2.s))*sgn((l1.e - l2.s) ^ (l2.e - l2.s)) < 0;
 62 }
 63 P p[MAXN];
 64 L l[MAXN];
 65 double a[MAXN][MAXN];
 66 int main()
 67 {
 68     int n = 0, m = 0;
 69     int N;
 70     while (scanf("%d", &N))
 71     {
 72         n = 0, m = 0;
 73         if (N == -1)    return 0;
 74         p[++n] = P(0, 5);
 75         for (int i = 1; i <= N; i++)
 76         {
 77             double x;
 78             double y[7];
 79             y[0] = 0, y[5] = 10;
 80             scanf("%lf%lf%lf%lf%lf", &x, &y[1], &y[2], &y[3], &y[4]);
 81             for (int j = 1; j <= 4; j++)    p[++n] = P(x, y[j]);
 82             for (int j = 1; j <= 5; j += 2)    l[++m] = L(P(x, y[j - 1]), P(x, y[j]));
 83         }
 84         p[++n] = P(10, 5);
 85         for (int i = 1; i <= n; i++)
 86             for (int j = 1; j <= n; j++)
 87                 a[i][j] = INF;
 88 
 89         for (int i = 1; i <= n; i++)
 90             for (int j = 1; j <= n; j++)
 91             {
 92                 if (i == j)
 93                 {
 94                     a[i][j] = 0;
 95                     continue;
 96                 }
 97                 bool flag = 1;
 98                 for (int k = 1; k <= m; k++)
 99                 {
100                     if (L_is_Inter(L(p[i], p[j]), l[k]))
101                     {
102                         flag = 0; break;
103                     }
104                 }
105                 if (flag)    a[i][j] = dis(p[i], p[j]);
106 
107             }
108         for (int i = 1; i <= n; i++)
109             for (int j = 1; j <= n; j++)
110                 for (int k = 1; k <= n; k++)
111                     if (a[i][k] + a[k][j] < a[i][j])
112                         a[i][j] = a[i][k] + a[k][j];
113         printf("%.2f\n", a[1][n]);
114     }
115     return 0;
116 }
View Code

 


 

【POJ 2653】Pick-up sticks

【题目大意】

给定 n 条木棍,按照顺序依次往下扔,问最后有哪几个木棍在最上面,输出编号

【题目分析】

木棍个数不多,直接暴力

 

【代码】

 

  1 #include<cstdio>
  2 #include<cmath>
  3 #include<iostream>
  4 #include<algorithm>
  5 #define sgn cmp
  6 #define e t
  7 #define ll double
  8 using namespace std;
  9 const int MAXN = 100010;
 10 const double eps = 1e-9;
 11 const double INF = 1e5;
 12 inline int cmp(double x)
 13 {
 14     if (x > eps)return 1;
 15     return x < -eps ? -1 : 0;
 16 }
 17 struct P
 18 {
 19     double x, y;
 20     P(double a = 0, double b = 0) :x(a), y(b) {}
 21     double operator ^(const P &b)const
 22     {
 23         return x * b.y - y * b.x;
 24     }
 25 };
 26 struct L
 27 {
 28     P s, t;
 29     L(P      a = P(0, 0), P      b = P(0, 0)) :s(a), t(b) {}
 30 };
 31 typedef P  V;
 32 bool operator ==(V a, V b) { return (cmp(a.x - b.x) == 0) && (cmp(a.y - b.y)); }
 33 V operator +(V a, V b) { return V(a.x + b.x, a.y + b.y); }
 34 V operator -(V a, V b) { return V(a.x - b.x, a.y - b.y); }
 35 V operator *(V a, double b) { return V(a.x *b, a.y*b); }
 36 double operator *(V a, V b) { return a.x*b.x + a.y*b.y; }
 37 V operator /(V a, double b) { return V(a.x / b, a.y / b); }
 38 double dis(P a, P b)
 39 {
 40     P tmp = b - a;
 41     return sqrt(tmp * tmp);
 42 }
 43 double cross(V a, V b)
 44 {
 45     return a.x*b.y - a.y*b.x;
 46 }
 47 double cross(P a, P b, P c)
 48 {
 49     return cross(b - a, c - a);
 50 }
 51 bool L_is_Inter(L l1, L l2)
 52 {
 53     return
 54         max(l1.s.x, l1.e.x) >= min(l2.s.x, l2.e.x) &&
 55         max(l2.s.x, l2.e.x) >= min(l1.s.x, l1.e.x) &&
 56         max(l1.s.y, l1.e.y) >= min(l2.s.y, l2.e.y) &&
 57         max(l2.s.y, l2.e.y) >= min(l1.s.y, l1.e.y) &&
 58         sgn((l2.s - l1.s) ^ (l1.e - l1.s))*sgn((l2.e - l1.s) ^ (l1.e - l1.s)) <= 0 &&
 59         sgn((l1.s - l2.s) ^ (l2.e - l2.s))*sgn((l1.e - l2.s) ^ (l2.e - l2.s)) <= 0;
 60 }
 61 L    l[MAXN];
 62 bool t[MAXN];
 63 int  ans[1010];
 64 int main()
 65 {
 66     int n;
 67     while (scanf("%d", &n) && n)
 68     {
 69         for (int i = 1; i <= n; i++)
 70         {
 71             double x1, x2, y1, y2;
 72             scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);
 73             l[i] = L(P(x1, y1), P(x2, y2));
 74             t[i] = true;
 75         }
 76         ans[0] = 0;
 77         for (int i = 1; i <= n; i++)
 78         {
 79             bool flag = 1;
 80             for (int j = i + 1; j <= n; j++)
 81             {
 82                 if (L_is_Inter(l[i], l[j]))
 83                 {
 84                     flag = 0;
 85                     break;
 86                 }
 87             }
 88             if (flag)    ans[++ans[0]] = i;
 89         }
 90         printf("Top sticks: ");
 91         for (int i = 1; i <=ans[0]; i++)
 92         {
 93             printf("%d", ans[i]);
 94             if (i == ans[0])
 95                 printf(".\n");
 96             else
 97                 printf(", ");
 98         }
 99     }
100     return 0;
101 }
View Code

 

 

 

 


 【POJ 1066】Treasure Hunt

【题目大意】 给定一个正方形,再给定N条直线,再给定一个点,问从这个点出去到外面需要打破几堵墙,即和多少条直线相交

【题目分析】 枚举这个点和其他直线顶点的连线,然后记录最小即可

 

 

【注意】

1.N等于0的情况

2.有关需不需要忽略顶点的需求

 

【代码】

 

  1 #include<cstdio>
  2 #include<cmath>
  3 #include<algorithm>
  4 #define e t
  5 #define ll double 
  6 using namespace std;
  7 const double eps  = 1e-9;
  8 const int    MAXN = 500;
  9 const int    INF  = 2e9;
 10 int sgn(ll x)
 11 {
 12     if (x > eps)    return 1;
 13     if (x < -eps)    return -1;
 14     return 0;
 15 }
 16 struct P
 17 {
 18     double x, y;
 19     P(double a = 0, double b = 0) : x(a), y(b) {}
 20     double operator ^(P a) { return x * a.y - y * a.x; }
 21     double operator *(P a) { return x * a.x + y * a.y; }
 22     P      operator *(double a)  { return P(x*a, y*a); }
 23     P      operator -(P a) { return P(x - a.x, y - a.y); }
 24     bool   operator==(P a) { return sgn(a.x - x) == 0 && sgn(a.y - y); }
 25 };
 26 typedef P V;
 27 struct L
 28 {
 29     P s, t;
 30     L(P a = P(0, 0), P b = P(0, 0)) :s(a), t(b) {}
 31 };
 32 double cross(P a, P b, P c)
 33 {
 34     return (b - a) ^ (c - a);
 35 }
 36 bool is_para(L a, L b)
 37 {
 38     return sgn((a.t - a.s) ^ (b.t - b.s))==0;
 39 }
 40 bool onL(L a, P b)
 41 {
 42     V check = P(b - a.s);
 43     V tmp   = a.t - a.s ;
 44     if (!is_para(a, check))    return 0;
 45     return tmp*tmp > check*check;
 46 }
 47 bool L_is_inter(L l1, L l2)
 48 {
 49     return
 50         max(l1.s.x, l1.e.x) >= min(l2.s.x, l2.e.x) &&
 51         max(l2.s.x, l2.e.x) >= min(l1.s.x, l1.e.x) &&
 52         max(l1.s.y, l1.e.y) >= min(l2.s.y, l2.e.y) &&
 53         max(l2.s.y, l2.e.y) >= min(l1.s.y, l1.e.y) &&
 54         sgn((l2.s - l1.s) ^ (l1.e - l1.s))*sgn((l2.e - l1.s) ^ (l1.e - l1.s)) < 0 &&
 55         sgn((l1.s - l2.s) ^ (l2.e - l1.s))*sgn((l1.e - l2.s) ^ (l2.e - l2.s)) < 0;
 56 }
 57 L l[MAXN];
 58 P p[MAXN];
 59 int main()
 60 {
 61     int N;
 62     scanf("%d", &N);
 63     if (N == 0)
 64     {
 65         printf("Number of doors = 1");
 66         return 0;
 67     }
 68         int n = 0,m = 0;
 69         for (int i = 1; i <= N; i++)
 70         {
 71             ll x1, x2, y1, y2;
 72             scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);
 73             l[++m] = L(P(x1, y1), P(x2, y2));
 74             p[++n] = P(x1, y1), p[++n] = P(x2, y2);
 75         }
 76         P beg;
 77         scanf("%lf%lf", &beg.x, &beg.y);
 78         int ans = INF;
 79         int pos;
 80         for (int i = 1; i <= n; i++)
 81         {
 82             int cnt = 0;
 83             L check = L(beg, p[i]);
 84             for (int j = 1; j <= m; j++)
 85             {
 86                 if (L_is_inter(check, l[j]))
 87                 {
 88                     cnt++;
 89     //                l1[++siz] = l[j];    
 90                 }
 91             }
 92             if (cnt < ans)
 93             {
 94                 ans = cnt;
 95             }
 96         }
 97         printf("Number of doors = %d", ans+1);
 98     
 99     return 0;
100 }
View Code

 


 【POJ 1410】Intersection

【题目大意】

给定一个线段的起始点和终止点,再给定一个矩形的左上点和右下点,求这个线段是否和矩形相交,相交输出“T”,否则输出“F”

【题目分析】

好,又是一道裸题

但是注意,线段包含在矩形中时,输出“ T ”

 

【代码】

 

 1 #include<cstdio>
 2 #include<cmath>
 3 #include<algorithm>
 4 #define e t
 5 #define ll double 
 6 using namespace std;
 7 const double eps = 1e-9;
 8 int sgn(ll x)
 9 {
10     if (x > eps)    return 1;
11     if (x < -eps)    return -1;
12     return 0;
13 }
14 struct P
15 {
16     double x, y;
17     P(double a = 0, double b = 0) : x(a), y(b) {}
18     double operator ^(P a) { return x * a.y - y * a.x; }
19     double operator *(P a) { return x * a.x + y * a.y; }
20     P      operator *(double a) { return P(x*a, y*a); }
21     P      operator -(P a) { return P(x - a.x, y - a.y); }
22     bool   operator==(P a) { return sgn(a.x - x) == 0 && sgn(a.y - y); }
23 };
24 typedef P V;
25 struct L
26 {
27     P s, t;
28     L(P a = P(0, 0), P b = P(0, 0)) :s(a), t(b) {}
29 };
30 double cross(P a, P b, P c)
31 {
32     return (b - a) ^ (c - a);
33 }
34 bool L_is_inter(L l1, L l2)
35 {
36     return
37         max(l1.s.x, l1.e.x) >= min(l2.s.x, l2.e.x) &&
38         max(l2.s.x, l2.e.x) >= min(l1.s.x, l1.e.x) &&
39         max(l1.s.y, l1.e.y) >= min(l2.s.y, l2.e.y) &&
40         max(l2.s.y, l2.e.y) >= min(l1.s.y, l1.e.y) &&
41         sgn((l2.s - l1.s) ^ (l1.e - l1.s))*sgn((l2.e - l1.s) ^ (l1.e - l1.s)) <= 0 &&
42         sgn((l1.s - l2.s) ^ (l2.e - l1.s))*sgn((l1.e - l2.s) ^ (l2.e - l2.s)) <= 0;
43 }
44 L line[10];
45 int main()
46 {
47     int T;
48     scanf("%d", &T);
49     while (T--)
50     {
51         L l;
52         int n = 0;
53         scanf("%lf %lf %lf %lf", &l.s.x, &l.s.y, &l.t.x, &l.t.y);
54         double x1, x2, y1, y2;
55         scanf("%lf %lf %lf %lf", &x1, &y1, &x2, &y2);
56         if (x1 > x2) swap(x1, x2);
57         if (y1 < y2) swap(y1, y2);
58         line[++n] = L(P(x1, y1), P(x2, y1));
59         line[++n] = L(P(x1, y1), P(x1, y2));
60         line[++n] = L(P(x2, y1), P(x2, y2));
61         line[++n] = L(P(x1, y2), P(x2, y2));
62         bool flag = false;
63         for (int i = 1; i <= n; i++)
64         {
65             if (L_is_inter(line[i], l))
66             {
67                 flag = true;
68                 break;
69             }
70         }
71         if (l.s.x >= x1 && l.s.x <= x2
72             && l.t.x >= x1 && l.t.x <= x2
73             && l.s.y >= y2 && l.s.y <= y1
74             && l.t.y >= y2 && l..y <= y1)
75             flag = true;
76         printf("%c\n", flag ? 'T' : 'F');
77     }
78         return 0;
79 }
View Code

 


 

posted @ 2019-09-29 16:03  rentu  阅读(264)  评论(0编辑  收藏  举报