NWERC 2015 Problem H: Hole in One

Posted HITLJR

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了NWERC 2015 Problem H: Hole in One相关的知识,希望对你有一定的参考价值。

暴力计算几何。。

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 const double eps = 1e-10;
  4 inline int sgn(double x)
  5 {
  6     if (fabs(x) < eps)
  7         return 0;
  8     if (x < 0)
  9         return -1;
 10     return 1;
 11 }
 12 struct Point
 13 {
 14     double x, y;
 15     Point() {}
 16     Point(double x, double y): x(x), y(y) {}
 17     void input()
 18     {
 19         scanf("%lf%lf", &x, &y);
 20     }
 21     double operator^(const Point &b)const
 22     {
 23         return x * b.y - y * b.x;
 24     }
 25     double operator*(const Point &b)const
 26     {
 27         return x * b.x + y * b.y;
 28     }
 29     Point operator-(const Point &b)const
 30     {
 31         return Point(x - b.x, y - b.y);
 32     }
 33 } hole, a[15], b[15];
 34 struct Line
 35 {
 36     Point s, e;
 37     Line() {}
 38     Line(Point s, Point e): s(s), e(e) {}
 39     int segcrossseg(Line v)
 40     {
 41         int d1 = sgn((e - s) ^ (v.s - s));
 42         int d2 = sgn((e - s) ^ (v.e-s));
 43         int d3 = sgn((v.e-v.s) ^ (s - v.s));
 44         int d4 = sgn((v.e-v.s) ^ (e - v.s));
 45         if ((d1 ^ d2) == -2 && (d3 ^ d4) == -2)
 46             return 2;
 47         return (d1 == 0 && sgn((v.s - s) * (v.s - e)) <= 0) ||
 48                (d2 == 0 && sgn((v.e-s) * (v.e-e)) <= 0) ||
 49                (d3 == 0 && sgn((s - v.s) * (s - v.e)) <= 0) ||
 50                (d4 == 0 && sgn((e - v.s) * (e - v.e)) <= 0);
 51     }
 52 } wall[15];
 53 int n;
 54 vector<int> per;
 55 int vis[15];
 56 inline bool gao()
 57 {
 58     memset(vis, 0, sizeof(vis));
 59     double xx = 0, yy = 0;
 60     double nowx = 0, nowy = 0;
 61     int flagx = 0, flagy = 0;
 62     int bx = 0, by = 0;
 63     /*判断反射方向,求反射长度*/
 64     for (int j = 0; j < (int)per.size(); ++j)
 65     {
 66         int id = per[j];
 67         /*讨论竖直水平*/
 68         if (sgn(wall[id].s.x - wall[id].e.x) == 0)
 69         {
 70             if (flagx == 0)
 71             {
 72                 flagx = sgn(wall[id].s.x - nowx);
 73                 if (sgn(wall[id].s.x - nowx) == 0 ) return 0;
 74                 bx = flagx;
 75             }
 76             else
 77             {
 78                 if (flagx == sgn(wall[id].s.x - nowx)) return 0;
 79                 if (sgn(wall[id].s.x - nowx) == 0 ) return 0;
 80                 flagx = -flagx;
 81             }
 82             xx += fabs(wall[id].s.x - nowx);
 83             nowx = wall[id].s.x;
 84         }
 85         else if (sgn(wall[id].s.y - wall[id].e.y) == 0)
 86         {
 87             if (flagy == 0)
 88             {
 89                 flagy = sgn(wall[id].s.y - nowy);
 90                 if (sgn(wall[id].s.y - nowy) == 0 ) return 0;
 91                 by = flagy;
 92             }
 93             else
 94             {
 95                 if (flagy == sgn(wall[id].s.y - nowy)) return 0;
 96                 if (sgn(wall[id].s.y - nowy) == 0 ) return 0;
 97                 flagy = -flagy;
 98             }
 99             yy += fabs(wall[id].s.y - nowy);
100             nowy = wall[id].s.y;
101         }
102     }
103     /*判断最后一下方向*/
104     if (bx == 0) bx = 1;
105     if (by == 0) by = 1;
106     // 默认右上角
107     xx += fabs(hole.x - nowx);
108     yy += fabs(hole.y - nowy);
109     if (sgn(hole.x - nowx) == flagx && flagx != 0) return 0;
110     if (sgn(hole.y - nowy) == flagy && flagy != 0) return 0;
111     //  回不到洞
112     /*遍历反射过程*/
113     double tmp = yy / xx;
114     int tmpflag = 0;
115     if (sgn(xx) == 0) tmpflag = 1;
116     nowx = 0, nowy = 0;
117     for (int j = 0; j < (int)per.size(); ++j)
118     {
119         int id = per[j];
120         if (sgn(wall[id].s.x - wall[id].e.x) == 0)
121         {
122             double tmpx = fabs(wall[id].s.x - nowx);
123             double zz;
124             if (tmpflag == 0)zz = tmpx * tmp * by;
125             else zz = 0;
126             Point pp(wall[id].s.x, nowy + zz);
127             Line ll(pp, Point(nowx, nowy));
128             if (ll.segcrossseg(wall[id]))
129             {
130                 vis[id] = 1;
131                 for (int i = 0 ; i < n; i++)
132                 {
133                     if (vis[i]) continue;
134                     if(ll.segcrossseg(wall[i])) return 0;
135                 }
136             }
137             else return 0;
138             bx = -bx;
139             nowx = pp.x ;
140             nowy = pp.y;
141         }
142         else
143         {
144             double tmpy = fabs(wall[id].s.y - nowy);
145             double zz;
146             if (tmpflag == 0)zz = tmpy / tmp * bx;
147             else zz = 0;
148             Point pp(nowx + zz, wall[id].s.y);
149             Line ll(pp, Point(nowx, nowy));
150             if (ll.segcrossseg(wall[id]))
151             {
152                 vis[id] = 1;
153                 for (int i = 0 ; i < n; i++)
154                 {
155                     if (vis[i]) continue;
156                     if(ll.segcrossseg(wall[i])) return 0;
157                 }
158             }
159             else return 0;
160             by = -by;
161             nowx = pp.x ;
162             nowy = pp.y;
163         }
164     }
165     /*最后一次相交*/
166     double tmpx = fabs(hole.x - nowx);
167     double tmpy = fabs(hole.y - nowy);
168     double zz;
169     if (tmpflag == 0)zz = tmpx * tmp * by;
170     else zz = 0;
171     Point pp(hole.x, nowy + zz);
172     if (sgn(pp.y - (nowy + zz)) != 0) return 0;
173     Line ll(pp, Point(nowx, nowy));
174     for (int i = 0 ; i < n; i++)
175     {
176         if (vis[i]) continue;
177         if(ll.segcrossseg(wall[i])) return 0;
178     }
179     return 1;
180 }
181 
182 inline int solve(int mask)
183 {
184     per.clear();
185     for (int i = 0; i < n; ++i)
186         if ((mask >> i) & 1)
187             per.push_back(i);
188     int ret = 0;
189     do
190     {
191         if (gao()) return per.size();
192     }
193     while (next_permutation(per.begin(), per.end()));
194     return -1;
195 }
196 int main()
197 {
198     scanf("%d", &n);
199     hole.input();
200     for (int i = 0; i < n; ++i)
201     {
202         a[i].input();
203         b[i].input();
204     }
205     if (sgn(hole.x) < 0)
206     {
207         for (int i = 0; i < n; ++i)
208         {
209             a[i].x = -a[i].x;
210             b[i].x = -b[i].x;
211         }
212         hole.x = -hole.x;
213     }
214     if (sgn(hole.y) < 0)
215     {
216         for (int i = 0; i < n; ++i)
217         {
218             a[i].y = -a[i].y;
219             b[i].y = -b[i].y;
220         }
221         hole.y = -hole.y;
222     }
223     for (int i = 0; i < n; ++i)
224         wall[i] = Line(a[i], b[i]);
225     int st = 1 << n, res = -1;
226     for (int i = 0; i < st; ++i)
227         res = max(res, solve(i));
228     if (res == -1) puts("impossible");
229     else printf("%d\n", res);
230     return 0;
231 }

 

以上是关于NWERC 2015 Problem H: Hole in One的主要内容,如果未能解决你的问题,请参考以下文章

NWERC2016-Problem A(Arranging Hat)

COGS——T 803. [USACO Hol10] 政党 || 1776: [Usaco2010 Hol]cowpol 奶牛政坛

bzoj 4428: [Nwerc2015]Debugging调试

bzoj 4430: [Nwerc2015]Guessing Camels赌骆驼

4425: [Nwerc2015]Assigning Workstations分配工作站

BZOJ4428[Nwerc2015]Debugging调试 记忆化搜索+分块