返回列表 回复 发帖 免费斗地主赢30元充值卡

[几何] [2847] How Far Can We Go 第七次训练赛

相关搜索: Can, Far, How, 训练
凸包 + 随机投点 (标准算法应该是 凸包 + 旋转卡壳)

没什么好说,先求出凸包,然后随机投点。投啊投,就AC了
  1. #include <iostream>
  2. #include <algorithm>
  3. #include <cmath>
  4. #include <string>
  5. #include <set>
  6. #include <queue>
  7. #include <map>
  8. using namespace std;

  9. #define MAXN 100011
  10. #define eps 1e-8

  11. struct point { double x, y; };

  12. point p[MAXN];
  13. int stack[MAXN];
  14. point s;

  15. bool zero(double x) { return ((x)>0?(x):-(x))<eps;}

  16. double dist(point a, point b)
  17. {
  18.     double p = a.x - b.x, q = a.y - b.y;
  19.     return p*p + q*q;
  20. }

  21. double xmult(point a, point b, point c)
  22. {
  23.     return   (c.x - a.x)*(b.y - a.y) - (b.x - a.x)*(c.y - a.y) ;
  24. }

  25. bool cmp(point a, point b)
  26. {
  27.     double t = xmult(s, a, b);
  28.     if (!zero(t)) return t < 0;
  29.     return dist(s, a) > dist(s, b);
  30. }

  31. int graham(int n)
  32. {
  33.         int i;
  34.        
  35.         for(i=1;i<n;i++)
  36.         {
  37.                 if( p[ i ].y<p[0].y ||( p[ i ].y==p[0].y && p[ i ].x<p[0].x ))
  38.                         swap(p[ i ],p[0]);
  39.         }
  40.        
  41.         s=p[0];
  42.         sort(p+1,p+n,cmp);
  43.         stack[0]=0;
  44.         stack[1]=1;
  45.        
  46.         int slip=2;
  47.         double t;
  48.         for(i=2;i<n;i++)
  49.         {
  50.                 t=xmult(p[0], p[i-1], p[ i ]);
  51.                 if(zero(t))continue;
  52.                 while (xmult(p[stack[slip-2]], p[stack[slip-1]], p[ i ]) >0) slip--;
  53.                
  54.                 stack[slip]=i;
  55.                 slip++;
  56.         }
  57.         return slip;
  58. }

  59. int main()
  60. {
  61.         //freopen("test.txt","r",stdin);
  62.         int n, i, j, all, time;
  63.         double temp, ans;
  64.         while(scanf("%d", &n) != EOF && n != 0)
  65.         {
  66.                 for(i=0; i<n; i++)
  67.                         scanf("%lf %lf", &p[ i ].x, &p[ i ].y);
  68.                
  69.                 all = graham ( n );
  70.                
  71.                 if(ans < 100)time = all * 10;
  72.                 else time = all * 30;
  73.                 ans = 0;
  74.                 while(time--)
  75.                 {
  76.                         i = rand()%all;
  77.                         j = rand()%all;
  78.                         temp = dist (p[stack[ i ]], p[stack[j]]);
  79.                         if(temp > ans)
  80.                                 ans = temp;
  81.                 }
  82.                
  83.                 printf("%.2lf\n", sqrt(ans));
  84.         }
  85.        
  86.        
  87.         return 0;
  88. }

  89. /*Power By GDUT_CHC*/
复制代码
不知道何为“旋转卡壳”
旋转卡壳过啦 嘿嘿 1.08秒 原来少考虑了1个小概率事件下的1个点
像赫尔一样性感.
旋转卡壳也这么慢 , 那么那些0.20的是如何做到的?
返回列表