hdu 3952 计算几何 暴力

枚举两个多边形的两个点组成的直线,判断能与几个多边形相交

因为最佳的直线肯定可以经过某两个点(可以平移到顶点处),所以暴力枚举两个点就好了

View Code
  1 #include <cstdio>
2 #include <cstring>
3 #include <cmath>
4 #include <algorithm>
5 using namespace std;
6 const double eps = 1e-8;
7 const double pi = acos(-1.0);
8 struct Point {
9 double x, y;
10 Point operator - (const Point& t) const {
11 Point tmp;
12 tmp.x = x - t.x;
13 tmp.y = y - t.y;
14 return tmp;
15 }
16 Point operator + (const Point& t) const {
17 Point tmp;
18 tmp.x = x + t.x;
19 tmp.y = y + t.y;
20 return tmp;
21 }
22 bool operator == (const Point& t) const {
23 return fabs(x-t.x) < eps && fabs(y-t.y) < eps;
24 }
25 };
26 struct pol{
27 Point node[11];
28 int num;
29 }P[11];
30 inline double Cross(Point a, Point b, Point c) { // 叉积
31 return (b.x-a.x)*(c.y-a.y) - (c.x-a.x)*(b.y-a.y);
32 }
33 bool dotOnSeg(Point p, Point s, Point e) { // 点是否在线段上
34 if ( p == s || p == e ) // 看具体情况端点是否合法
35 return true;
36 return Cross(p,s,e) < eps &&
37 (p.x-s.x)*(p.x-e.x)<eps && (p.y-s.y)*(p.y-e.y)<eps;
38 }
39 struct Line {
40 double a, b, c;
41 };
42 Line Turn(Point s, Point e) { // 线段转直线表达式
43 Line ln;
44 ln.a = s.y - e.y;
45 ln.b = e.x - s.x;
46 ln.c = s.x*e.y - e.x*s.y;
47 return ln;
48 }
49 bool Line_Inst(Line l1, Line l2, Point &p) { // 直线相交
50 double d = l1.a*l2.b - l2.a*l1.b;
51 if ( fabs(d) < eps ) return false;
52 p.x = (-l1.c*l2.b + l2.c*l1.b) / d;
53 p.y = (-l1.a*l2.c + l2.a*l1.c) / d;
54 return true;
55 }
56 int main()
57 {
58 int t,i,j,k,cases=1;
59 scanf("%d",&t);
60 int x,y,m,n,ans;
61 while(t--)
62 {
63 scanf("%d",&n);
64
65 for(i=1;i<=n;i++)
66 {
67 scanf("%d",&P[i].num);
68 for(j=1;j<=P[i].num;j++)
69 scanf("%lf%lf",&P[i].node[j].x,&P[i].node[j].y);
70 }
71 if(n<=2){ printf("Case %d: %d\n",cases++,n);continue;}
72 Point p;
73 int max=0;
74 for(i=1;i<=n;i++)
75 {
76 for(j=i+1;j<=n;j++)
77 {
78 for(k=1;k<=P[i].num;k++)
79 {
80 for(m=1;m<=P[j].num;m++)
81 {
82 ans=2;
83 Line a=Turn(P[i].node[k],P[j].node[m]) ;
84 for(x=1;x<=n;x++)
85 {
86 if(x==i||x==j) continue;
87 for(y=1;y<P[x].num;y++)
88 {
89 Line b=Turn(P[x].node[y],P[x].node[y+1]);
90 if(Line_Inst(a,b,p)&&dotOnSeg(p,P[x].node[y],P[x].node[y+1]))
91 {
92 ans++;
93 break;
94 }
95 }
96 }
97 if(ans>max) max=ans;
98 }
99 }
100 }
101 }
102 printf("Case %d: %d\n",cases++,max);
103 }
104 return 0;
105 }

 

你可能感兴趣的:(HDU)