HDU 4353

利用分式的性质可以很容易证明要求的是个三角形,这很简单。对于求三角形内的雷的个数,只需求出每条边上方有多少个雷,作一点运算即可。如

A,B,C(B是X轴坐标在中间的点),则AC(其上方的雷的个数)-AB-BC即可。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cmath>
 5 using namespace std;
 6 
 7 struct node{
 8     int x,y;
 9 };
10 node point[250],mine[550];
11 int cpoint[250][250];
12 
13 void exchange(int &i,int &j){
14     int tmp=i;
15     i=j;
16     j=tmp;
17 }
18 
19 int count_point(int i,int j,int cm){
20     int cp=0;
21     if(point[i].x>point[j].x)
22     exchange(i,j);
23     for(int k=0;k<cm;k++){
24         if(mine[k].x>=point[i].x&&mine[k].x<point[j].x){\\必须是开区间,否则会有重复计算,对于中间的一点。。 
25             if((point[i].x-mine[k].x)*(point[j].y-mine[k].y)-(point[j].x-mine[k].x)*(point[i].y-mine[k].y)>0)
26             cp++;
27         }
28     }
29     return cp;
30 }
31 
32 int main(){
33     int T,n,m,kase=0;
34     scanf("%d",&T);
35     while(T--){
36         double ans=1e15;
37         scanf("%d%d",&n,&m);
38         for(int i=0;i<n;i++){
39             scanf("%d%d",&point[i].x,&point[i].y);
40         }
41         for(int i=0;i<m;i++){
42             scanf("%d%d",&mine[i].x,&mine[i].y);
43         }
44         memset(cpoint,0,sizeof(cpoint));
45         for(int i=0;i<n;i++){
46             for(int j=i+1;j<n;j++)
47             cpoint[i][j]=count_point(i,j,m);
48         }
49         int i,j,k;
50         for(int ii=0;ii<n;ii++){
51             for(int jj=ii+1;jj<n;jj++){
52                 for(int kk=jj+1;kk<n;kk++){
53                     i=ii; j=jj;k=kk;
54                     if(point[i].x>=min(point[j].x,point[k].x)&&point[i].x<=max(point[j].x,point[k].x))
55                     exchange(i,i);
56                     else if(point[j].x>=min(point[i].x,point[k].x)&&point[j].x<=max(point[i].x,point[k].x))
57                     exchange(i,j);
58                     else if(point[k].x>=min(point[i].x,point[j].x)&&point[k].x<=max(point[i].x,point[j].x))
59                     exchange(i,k);
60                     double area=fabs(((point[j].x-point[i].x)*(point[k].y-point[i].y)-(point[k].x-point[i].x)*(point[j].y-point[i].y))/2.0);
61                     double cp=abs((cpoint[i][j]+cpoint[j][i])+(cpoint[i][k]+cpoint[k][i])-(cpoint[j][k]+cpoint[k][j]));
62                     ans=min(ans,area/cp);
63                 }
64             }
65         }
66         printf("Case #%d: ",++kase);
67         if(ans==1e15)
68         printf("-1\n");
69         else printf("%.6lf\n",ans);
70     }
71     return 0;
72 }

 

posted @ 2015-02-03 09:48  chenjunjie1994  阅读(160)  评论(0编辑  收藏  举报