zoukankan      html  css  js  c++  java
  • 计算几何 之 hdu 1077 poj 1981 O(n^3)

    注意两题输入格式不同。。。O(n^3),确实有更优的解法 O(n^2logn)   详解+代码,请点击这里

    /*
     
    题目: 用半径为 1.0001 的圆,尽可能多的包含所给点。
     
    第一次做这样的计算几何题,,,感觉挺麻烦的,,特别精度的把握上。。。
     
    思路:
    1)任意两点间的距离大于直径(2.0002),则答案为 1 ;
    2)若不满足1),则在圆上必存在两个点,而这两个点也正好确定了这个圆,
    	故遍历所有点,看有多少个点在圆中,满足条件点的个数即答案。
     
    关键:
    判断点是否在圆中: 可用此点到原点的距离与半径作比较判断
    故关键在于如何求原点?
    	两个点确定中垂线 + 半径长 => 原点 (具体实现看代码,一些细节东西需要注意)
     
    另外:
    由于两个点可以确定两个圆心,但取一个就好。
    (
    严格地数学证明,没找到;但是,想一下三个点的情况:
    假设三个点分别为a、b、c,若三个点在同一个半径为1.0001的圆内,
    即使a、b没包含c,a、c没包含b,但是b、c一定可以包含a,
    前提:代码中求任意两个点所对应的圆心时,或者都 '+' ,或者都 '-' (具体看函数 void Get_Center(int i, int j))
    )
     1 */
     2 // hdu 1077 
     3 #include <iostream>
     4 #include <cstdlib>
     5 #include <cstdio>
     6 #include <cmath>
     7 #include <algorithm>
     8 using namespace std;
     9 const int MAX = 305;
    10 const double eps = 1e-6;
    11 
    12 double arr_p[MAX][2];
    13 double center[2];
    14 
    15 double Distance(double p1[], double p2[])
    16 {
    17     return sqrt((p2[0] - p1[0])*(p2[0] - p1[0]) + (p2[1] - p1[1])*(p2[1] - p1[1]));
    18 }
    19 
    20 void Get_Center(int i, int j){
    21     double p_mid[2];
    22     p_mid[0] = (arr_p[i][0] + arr_p[j][0]) / 2.0;
    23     p_mid[1] = (arr_p[i][1] + arr_p[j][1]) / 2.0;
    24 
    25     double dis_x, dis_y;
    26     dis_x = arr_p[i][0] - arr_p[j][0];
    27     dis_y = arr_p[i][1] - arr_p[j][1];
    28 
    29     double dis_mid_center = sqrt(1 - ((p_mid[0] - arr_p[i][0])*(p_mid[0] - arr_p[i][0]) + (p_mid[1] - arr_p[i][1])*(p_mid[1] - arr_p[i][1])));
    30 
    31     if (fabs(dis_y) < eps) { // 中垂线垂直于 x 轴
    32         center[0] = p_mid[0];
    33         center[1] = p_mid[1] + dis_mid_center;
    34         /*
    35         center[0] = p_mid[0];
    36         center[1] = p_mid[1] - dis_mid_center;
    37         */
    38     }
    39     else {
    40         double k = atan(-(dis_x / dis_y));
    41         double tep1 = dis_mid_center*cos(k);
    42         double tep2 = dis_mid_center*sin(k);
    43         center[0] = p_mid[0] + tep1;  // 皆采取 '+' 的方式
    44         center[1] = p_mid[1] + tep2;
    45         /*
    46         center[0] = p_mid[0] - tep1;  // 皆采取 '-' 的方式
    47         center[1] = p_mid[1] - tep2;
    48         */
    49     }
    50 }
    51 
    52 int main()
    53 {
    54     //freopen("input.txt", "r", stdin);
    55     int T;
    56     scanf("%d", &T);
    57     while (T--) {
    58         int N, tep;
    59         scanf("%d", &N);
    60         for (int i = 0; i < N; i++) {
    61             scanf("%lf %lf", &arr_p[i][0], &arr_p[i][1]);
    62         }
    63         int ans = 1;
    64         for (int i = 0; i < N; i++) {
    65             for (int j = i + 1; j < N; j++) {
    66                 if (Distance(arr_p[i], arr_p[j]) > 2.0) {
    67                     continue;
    68                 }
    69 
    70                 Get_Center(i, j);
    71 
    72                 tep = 2;
    73                 for (int k = 0; k < N; k++) {
    74                     if (k == i || k == j) {
    75                         continue;
    76                     }
    77                     if (Distance(arr_p[k], center) <= 1.0001) {
    78                         tep++;
    79                     }
    80                 }
    81                 ans = max(ans, tep);
    82             }
    83         }
    84         printf("%d
    ", ans);
    85     }
    86     return 0;
    87 }
    
    
    
    
    
     1 // poj 1981
     2 #include <iostream>
     3 #include <cstdlib>
     4 #include <cstdio>
     5 #include <cmath>
     6 #include <algorithm>
     7 using namespace std;
     8 const int MAX = 305;
     9 const double eps = 1e-6;
    10 
    11 double arr_p[MAX][2];
    12 double center[2];
    13 
    14 double Distance(double p1[], double p2[])
    15 {
    16     return sqrt((p2[0] - p1[0])*(p2[0] - p1[0]) + (p2[1] - p1[1])*(p2[1] - p1[1]));
    17 }
    18 
    19 void Get_Center(int i, int j){
    20     double p_mid[2];
    21     p_mid[0] = (arr_p[i][0] + arr_p[j][0]) / 2.0;
    22     p_mid[1] = (arr_p[i][1] + arr_p[j][1]) / 2.0;
    23 
    24     double dis_x, dis_y;
    25     dis_x = arr_p[i][0] - arr_p[j][0];
    26     dis_y = arr_p[i][1] - arr_p[j][1];
    27 
    28     double dis_mid_center = sqrt(1 - ((p_mid[0] - arr_p[i][0])*(p_mid[0] - arr_p[i][0]) + (p_mid[1] - arr_p[i][1])*(p_mid[1] - arr_p[i][1])));
    29 
    30     if (fabs(dis_y) < eps) {
    31         center[0] = p_mid[0];
    32         center[1] = p_mid[1] + dis_mid_center;
    33     }
    34     else {
    35         double k = atan(-(dis_x / dis_y));
    36         double tep1 = dis_mid_center*cos(k);
    37         double tep2 = dis_mid_center*sin(k);
    38         center[0] = p_mid[0] + tep1;
    39         center[1] = p_mid[1] + tep2;
    40     }
    41 }
    42 
    43 int main()
    44 {
    45     int N;
    46     while (scanf("%d", &N) && N) {
    47         int tep;
    48 
    49         for (int i = 0; i < N; i++) {
    50             scanf("%lf %lf", &arr_p[i][0], &arr_p[i][1]);
    51         }
    52         int ans = 1;
    53         for (int i = 0; i < N; i++) {
    54             for (int j = i + 1; j < N; j++) {
    55                 if (Distance(arr_p[i], arr_p[j]) > 2.0002) {
    56                     continue;
    57                 }
    58 
    59                 Get_Center(i, j);
    60 
    61                 tep = 2;
    62                 for (int k = 0; k < N; k++) {
    63                     if (k == i || k == j) {
    64                         continue;
    65                     }
    66                     if (Distance(arr_p[k], center) <= 1.0001) {
    67                         tep++;
    68                     }
    69                 }
    70                 ans = max(ans, tep);
    71             }
    72         }
    73         printf("%d
    ", ans);
    74     }
    75     return 0;
    76 }


  • 相关阅读:
    git使用代理
    反汇编一个c程序
    Berkeley套接字
    ubuntu 升级
    ubuntu备份与还原
    struct socket 结构详解
    How sockets work
    wget中文乱码问题
    ubuntu配置开机启动服务
    《javascript设计模式》笔记之第五章:单体模式
  • 原文地址:https://www.cnblogs.com/shijianming/p/4140837.html
Copyright © 2011-2022 走看看