|
  
|
1#
发表于 2008-8-27 22:57
| 只看该作者
[几何] [2847] How Far Can We Go 第七次训练赛
凸包 + 随机投点 (标准算法应该是 凸包 + 旋转卡壳)
没什么好说,先求出凸包,然后随机投点。投啊投,就AC了- #include <iostream>
- #include <algorithm>
- #include <cmath>
- #include <string>
- #include <set>
- #include <queue>
- #include <map>
- using namespace std;
- #define MAXN 100011
- #define eps 1e-8
- struct point { double x, y; };
- point p[MAXN];
- int stack[MAXN];
- point s;
- bool zero(double x) { return ((x)>0?(x):-(x))<eps;}
- double dist(point a, point b)
- {
- double p = a.x - b.x, q = a.y - b.y;
- return p*p + q*q;
- }
- double xmult(point a, point b, point c)
- {
- return (c.x - a.x)*(b.y - a.y) - (b.x - a.x)*(c.y - a.y) ;
- }
- bool cmp(point a, point b)
- {
- double t = xmult(s, a, b);
- if (!zero(t)) return t < 0;
- return dist(s, a) > dist(s, b);
- }
- int graham(int n)
- {
- int i;
-
- for(i=1;i<n;i++)
- {
- if( p[ i ].y<p[0].y ||( p[ i ].y==p[0].y && p[ i ].x<p[0].x ))
- swap(p[ i ],p[0]);
- }
-
- s=p[0];
- sort(p+1,p+n,cmp);
- stack[0]=0;
- stack[1]=1;
-
- int slip=2;
- double t;
- for(i=2;i<n;i++)
- {
- t=xmult(p[0], p[i-1], p[ i ]);
- if(zero(t))continue;
- while (xmult(p[stack[slip-2]], p[stack[slip-1]], p[ i ]) >0) slip--;
-
- stack[slip]=i;
- slip++;
- }
- return slip;
- }
- int main()
- {
- //freopen("test.txt","r",stdin);
- int n, i, j, all, time;
- double temp, ans;
- while(scanf("%d", &n) != EOF && n != 0)
- {
- for(i=0; i<n; i++)
- scanf("%lf %lf", &p[ i ].x, &p[ i ].y);
-
- all = graham ( n );
-
- if(ans < 100)time = all * 10;
- else time = all * 30;
- ans = 0;
- while(time--)
- {
- i = rand()%all;
- j = rand()%all;
- temp = dist (p[stack[ i ]], p[stack[j]]);
- if(temp > ans)
- ans = temp;
- }
-
- printf("%.2lf\n", sqrt(ans));
- }
-
-
- return 0;
- }
- /*Power By GDUT_CHC*/
复制代码
|
|