HDU——1077 Catching fish(几何问题)

9人阅读 评论(1) 收藏 举报
分类:

Problem Description

Ignatius likes catching fish very much. He has a fishnet whose shape is a circle of radius one. Now he is about to use his fishnet to catch fish. All the fish are in the lake, and we assume all the fish will not move when Ignatius catching them. Now Ignatius wants to know how many fish he can catch by using his fishnet once. We assume that the fish can be regard as a point. So now the problem is how many points can be enclosed by a circle of radius one.

Note: If a fish is just on the border of the fishnet, it is also caught by Ignatius.

Input

The input contains several test cases. The first line of the input is a single integer T which is the number of test cases. T test cases follow.
Each test case starts with a positive integer N(1<=N<=300) which indicate the number of fish in the lake. Then N lines follow. Each line contains two floating-point number X and Y (0.0<=X,Y<=10.0). You may assume no two fish will at the same point, and no two fish are closer than 0.0001, no two fish in a test case are approximately at a distance of 2.0. In other words, if the distance between the fish and the centre of the fishnet is smaller 1.0001, we say the fish is also caught.

Output

For each test case, you should output the maximum number of fish Ignatius can catch by using his fishnet once.

Sample Input

4
3
6.47634 7.69628
5.16828 4.79915
6.69533 6.20378
6
7.15296 4.08328
6.50827 2.69466
5.91219 3.86661
5.29853 4.16097
6.10838 3.46039
6.34060 2.41599
8
7.90650 4.01746
4.10998 4.18354
4.67289 4.01887
6.33885 4.28388
4.98106 3.82728
5.12379 5.16473
7.84664 4.67693
4.02776 3.87990
20
6.65128 5.47490
6.42743 6.26189
6.35864 4.61611
6.59020 4.54228
4.43967 5.70059
4.38226 5.70536
5.50755 6.18163
7.41971 6.13668
6.71936 3.04496
5.61832 4.23857
5.99424 4.29328
5.60961 4.32998
6.82242 5.79683
5.44693 3.82724
6.70906 3.65736
7.89087 5.68000
6.23300 4.59530
5.92401 4.92329
6.24168 3.81389
6.22671 3.62210

Sample Output

2
5
5
11

解题思路:

枚举画圆 , 记录单位圆最多可以圈住的点的数量。
枚举选取其中两个点 , 如果两个点的距离小于2,则证明这两个点可以在同一个圆里面(注意:这里隐藏了 从每个最少放两个点的情况考虑 , 但是最后结果也有可能是 最多只能圈住一个点 ,这点对应在代码中 maxsum 的初值设定问题)。此时以这两个点可以确定一个半径为1 的 单位圆 , 主要求出圆心位置即可。然后在一个枚举 , 对比记录与这个圆心距离小于 1 的点的个数。

代码:

//枚举圆心
/* 选取任意两个点 , 求取两点所在的以 1 为半径的圆的圆心, 作圆 , 计算该圆中有多少点。*/
#include <cstdio>
#include <math.h>
using namespace std;

double x[305];
double y[305];
int n;

double distance1(int i , int  j){   //求 距离的平方
    double dis = 0;
    dis = (x[i] - x[j]) * (x[i] - x[j]) + (y[i] - y[j]) * (y[i] - y[j]);
    return dis;
}

void getCenter(int i , int j){   //求 圆心
    x[n+1] = (x[i] + x[j]) / 2;  //中心点
    y[n+1] = (y[i] + y[j]) / 2;

    double k = -1 *  (x[i] - x[j])/(y[i] - y[j]);
    //k1 * k2 = -1
    //float k2 = -1 / k1;   //中垂线的 k
    double rad = atan(k);

    double len = sqrt(1 - distance1( i , n + 1));   //中点 到 圆心 的距离

    x[n] = x[n+1] + (len * cos(rad));
    y[n] = y[n+1] + (len * sin(rad));

}

int main(){
    //freopen("D://testData//1077.txt","r",stdin);// 数据太多 , 直接从文件读
    int t , i , j , maxsum = 0, ans;

    scanf("%d" , &t);
    while(t -- ){
       ans = 0;
       maxsum = 1;    //!!!!一定不能是 0 呀 , 因为我们一下考虑的情况都是每个圈里最少有2个点 , 将一个点的都没有考虑。
       scanf("%d" , &n);

       for(i = 0 ; i < n ; i ++){
            scanf("%lf %lf" , &x[i] , &y[i]);
       }

       for(i = 0 ; i < n ; i ++){
            for(j = i + 1 ; j < n ; j ++){
                ans = 0;
                if(distance1(i , j) > 4){   //如果两点之间的距离的平方大于 4 , 那么就不考虑这个情况。
                    continue;
                }

                getCenter(i ,j);

                for(int k = 0 ; k < n ; k ++){
                    if(distance1(k , n) <= 1.001)
                        ans ++;
                }
                if(ans > maxsum)
                    maxsum = ans;
            }
       }
       printf("%d\n" , maxsum);

    }
    return 0;
}
查看评论

hdu 1077 Catching Fish

Catching Fish Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) T...
  • u011111528
  • u011111528
  • 2013-08-31 15:20:54
  • 718

hdu 1077 Catching Fish(计算几何)

Ignatius likes catching fish very much. He has a fishnet whose shape is a circle of radius one. Now ...
  • u013903504
  • u013903504
  • 2014-07-18 14:15:16
  • 545

hdu 1077 Catching Fish 计算几何(圆覆盖)

题意: 给定n个点,现在要求找一个点
  • a601025382s
  • a601025382s
  • 2014-08-13 12:42:13
  • 754

hdu 1077 Catching Fish 计算几何+暴力枚举

简单的暴力枚举,枚举两个点在圆上,用向量法求下圆心。复杂度o(n^3),但数据量只有300 /* author:jxy lang:C/C++ university:China,Xidia...
  • czjxy881
  • czjxy881
  • 2013-05-07 09:10:00
  • 774

HDU 1077 枚举圆心, 数学

从所有点中依次取两点,然后判断到两点m, n距离为半径1的点centre(易知center在m, n连线的中垂线上)。然后判断其余有多少点在以centre为圆心的圆内,记作ans,最后找出最大的ans...
  • vsooda
  • vsooda
  • 2012-09-23 20:27:35
  • 1316

hdu 3469 Catching the Thief

/* 为何比赛的时间就是想不到呢?还以为可以用2插排序树。。真的不知但是是怎么想的 其实模拟一下就可以出来的。。 */ #include using namespace std; i...
  • huixisheng
  • huixisheng
  • 2010-07-23 09:23:00
  • 453

Catching Fish

Catching Fish Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) ...
  • wenlovingliu
  • wenlovingliu
  • 2013-05-03 18:35:16
  • 376

HDU1818 Floyd 最短路问题(模板)简单题

变形课 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others) Total Sub...
  • FengTwoYear
  • FengTwoYear
  • 2015-12-03 11:27:10
  • 461

HDU1077关于简单几何

题目是平面有一些点,用一个单位圆去圈取,最多可以得到几个点。 求出两个点的圆心,根据这个圆心去查找有几个点在这个圆中,遍历一次两个点的圆心和遍历一下在圆中的数量。 涉及的是两个点和半径求圆心。(代...
  • zsj1415926
  • zsj1415926
  • 2015-10-15 15:12:08
  • 397

hdoj1077 Catching Fish(几何题,枚举遍历)

来源:http://acm.hdu.edu.cn/showproblem.php?pid=1077 可以由两个点确定两个圆心。圆心与两个点的距离为1,画图易知,圆心位于两点连线的中垂线上, 本题的...
  • CqZtw
  • CqZtw
  • 2017-06-11 10:21:53
  • 144
    个人资料
    持之以恒
    等级:
    访问量: 1万+
    积分: 912
    排名: 5万+
    文章分类
    最新评论