hdu 4353 Finding Mine (计算几何 2012 Multi-University Training Contest 6 )

http://acm.hdu.edu.cn/showproblem.php?pid=4353

 

题意:
给你n个点,m个雷
找一个多边形,使得多边形的面积除以这个多边形内雷的个数的比值最小
仔细想想,其实就是找一个比值最小的三角形就OK了,因为其他的三角形的比值都比它大,组合成多边形后势必会将比值变大
所以可以直接暴力O(n^3)枚举三角形,再计算三角形内的雷的个数求比值即可
雷得个数的话预处理一个数组吧,画张图就懂了
hdu 4353 Finding Mine (计算几何 2012 Multi-University Training Contest 6 )

cnt= (i k上方的点 )- ( i j上方的点 +    j k上方的点)  
当然还要取绝对值

 

 

 

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<cmath>
  4 #include<iostream>
  5 #include<algorithm>
  6 #include< set>
  7 #include<map>
  8 #include<queue>
  9 #include<vector>
 10 #include< string>
 11  #define Min(a,b) a<b?a:b
 12  #define Max(a,b) a>b?a:b
 13  #define CL(a,num) memset(a,num,sizeof(a));
 14  #define maxn  520
 15  #define eps  1e-8
 16  #define inf 100000000
 17  #define mx 1<<60
 18  #define ll   __int64
 19  using  namespace std;
 20  struct house
 21 {
 22      double  x;
 23      double y;
 24 }a[maxn],b[maxn];
 25  int cmp(house a,house b)
 26 {
 27      if(a.x == b.x)  return a.y < b.y ;
 28      else   return a.x < b.x ;
 29 }
 30  double   in(house a,house b,house c)
 31 {
 32       return (b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x);
 33 }
 34  double sgn(house a,house b,house c)
 35 {
 36       return fabs((c.x-a.x)*(b.y-a.y)-(c.y-a.y)*(b.x-a.x))* 0.5;
 37 }
 38  int dp[maxn][maxn] ;
 39  int main()
 40 {
 41      int n,m,i,j,k;
 42       int cas =  0;
 43       int t;
 44      scanf( " %d ",&t);
 45       while(t--)
 46      {
 47          scanf( " %d%d ",&n,&m);
 48           for(i =  0; i < n;i++)
 49          {
 50              scanf( " %lf%lf ",&a[i].x,&a[i].y);
 51 
 52          }
 53          sort(a,a + n,cmp);
 54           for(j =  0; j < m;j++)
 55          {
 56              scanf( " %lf%lf ",&b[j].x,&b[j].y);
 57 
 58          }
 59 
 60           for( i = 0 ; i < n;i++)
 61          {
 62               for(j = i +  1; j< n;j++)
 63              {
 64                  dp[i][j] =  0;
 65                   for(k =  0; k< m;k++)
 66                  {
 67                       if(b[k].x >= a[i].x&&b[k].x < a[j].x)
 68                          if( in(a[i],a[j],b[k]) >  0) dp[i][j]++;
 69                  }
 70 
 71 
 72              }
 73 
 74          }
 75           int f =  0 ;
 76           double  ans = - 1;
 77           for( i =  0;i< n;i++)
 78          {
 79               for(j=i+ 1;j< n;j++)
 80              {
 81                   for(k = j+ 1;k< n;k++)
 82                  {
 83                       double tmp = ( double )abs(dp[i][k] - dp[i][j] - dp[j][k]);
 84 
 85                       if(tmp ==  0) continue ;
 86                       double s = sgn(a[i],a[j],a[k]) ;
 87 
 88 
 89                      f =  1 ;
 90                       if(ans == - 1 || ans > fabs(s/tmp)) ans = fabs(s/tmp);
 91 
 92                  }
 93              }
 94          }
 95 
 96           if(f ==  0)printf( " Case #%d: -1\n ",++cas);
 97           else printf( " Case #%d: %.6lf\n ",++cas,ans);
 98 
 99      }
100 }

 

你可能感兴趣的:(test)