• 计算几何 之 hdu 1077 poj 1981 O(n^2logn)


    花了很长时间,终于理解了一些。。。

    注意两题输入格式不同。。。O(n^2logn) 

    有另一种非常好理解一些的算法,不过时间差点O(n^3),亦能AC  详解+代码,请点击这里 

    //  [7/10/2014 Sjm]
    // 题目: 用半径为 1 的圆,尽可能多的包含所给点。
     
    /***********************************************************************
    其实要理解时间复杂度为O(n^2lgn)的算法,首先要知道以下三点:
    1)若以一个点 p 为圆心,在半径为 1 的圆内,随便选一个点 p1,皆可捕获到点 p
    2)此时,我们把所给的点皆作为圆心,皆做半径为 1 的圆,
    3)在圆的交集中,所重叠的最高层数,即:所要求的答案。。。
    ************************************************************************/
    /*
    根据以上三点作为基础,理解网上的时间复杂度为O(n^2lgn)的算法,便比较容易了。。
     
    关键:将圆的重叠部分转换为弧的重叠部分。(这里可以自己画几个图理解一下)
     
    遍历每一个点
    	以此点 p 做半径为 1 的圆C,可以获得此圆C与以其他点为圆心所作圆Ci的相交弧(即圆C被圆Ci截取的那段弧),
    	存储该相交弧的起点以及终点的极角(并区分它们)到数组;
    	对此数组进行排序(若极角相等,端点:始点-->终点;否则,极角:小-->大)
    	此时遍历此数组
    		1)如果遇到起点,则sum++,表示此时弧可以有重叠 => 可以覆盖到数组此时所代表的点
    		在此过程中,若sum > ans, 则 ans = aum (ans 代表所要获得的答案)
    		2)如果遇到终点,则sum--,表示此弧已无法重叠 => 已覆盖不到数组此时所代表的点
    遍历结束,获得答案。   
     
    */
     1 //hdu 1077
     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 int N;
    11 double arr_p[MAX][2];
    12 
    13 double Angle[MAX][2];
    14 
    15 struct Angle_Jug {
    16     double angle; // 记录极角
    17     bool Judge;  // 判断方向:true->相交弧的起点,false->相交弧的终点
    18 };
    19 };
    20 
    21 Angle_Jug Aj[MAX];
    22 
    23 double Distance(int p1, int p2)
    24 {
    25     return sqrt((arr_p[p2][0] - arr_p[p1][0])*(arr_p[p2][0] - arr_p[p1][0]) +
    26         (arr_p[p2][1] - arr_p[p1][1])*(arr_p[p2][1] - arr_p[p1][1]));
    27 }
    28 
    29 bool Cmp(const Angle_Jug &ag1, const Angle_Jug &ag2) {
    30     if (ag1.angle == ag2.angle) {
    31         return (ag1.Judge > ag2.Judge);
    32     }
    33     return ag1.angle < ag2.angle;
    34 }
    35 
    36 int Solve(double R) {
    37     int ans = 1;
    38     for (int i = 0; i < N; i++) {
    39         int m = 0;
    40         for (int j = 0; j < N; j++) {
    41             double dis = Distance(i, j);
    42             if ((i == j) || (dis > 2 * R)) { continue; }
    43             double tep = acos((dis / 2.0) / R);
    44             double k = atan2(arr_p[j][1] - arr_p[i][1], arr_p[j][0] - arr_p[i][0]);
    45             Aj[m].angle = k - tep;  Aj[m++].Judge = true;
    46             Aj[m].angle = k + tep;  Aj[m++].Judge = false;
    47         }
    48         sort(Aj, Aj + m, Cmp);
    49         int sum = 1;
    50         for (int k = 0; k < m; k++) {
    51             if (Aj[k].Judge)  {
    52                 sum++;
    53                 ans = (ans > sum) ? ans : sum;
    54             }
    55             else { sum--; }
    56         }
    57     }
    58     return ans;
    59 }
    60 
    61 int main()
    62 {
    63     //freopen("input.txt", "r", stdin);
    64     int T;
    65     scanf("%d", &T);
    66     while (T--) {
    67         scanf("%d", &N);
    68         for (int i = 0; i < N; i++) {
    69             scanf("%lf %lf", &arr_p[i][0], &arr_p[i][1]);
    70         }
    71         printf("%d
    ", Solve(1.0));
    72     }
    73 }
     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 int N;
    11 double arr_p[MAX][2];
    12 
    13 double Angle[MAX][2];
    14 
    15 struct Angle_Jug {
    16     double angle; // 记录极角
    17     bool Judge;  // 判断方向:true->相交弧的起点,false->相交弧的终点
    18 };
    19 
    20 Angle_Jug Aj[MAX];
    21 
    22 double Distance(int p1, int p2)
    23 {
    24     return sqrt((arr_p[p2][0] - arr_p[p1][0])*(arr_p[p2][0] - arr_p[p1][0]) +
    25         (arr_p[p2][1] - arr_p[p1][1])*(arr_p[p2][1] - arr_p[p1][1]));
    26 }
    27 
    28 bool Cmp(const Angle_Jug &ag1, const Angle_Jug &ag2) {
    29     if (ag1.angle == ag2.angle) {
    30         return (ag1.Judge > ag2.Judge);
    31     }
    32     return ag1.angle < ag2.angle;
    33 }
    34 
    35 int Solve(double R) {
    36     int ans = 1;
    37     for (int i = 0; i < N; i++) {
    38         int m = 0;
    39         for (int j = 0; j < N; j++) {
    40             double dis = Distance(i, j);
    41             if ((i == j) || (dis > 2 * R)) { continue; }
    42             double tep = acos((dis / 2.0) / R);
    43             double k = atan2(arr_p[j][1] - arr_p[i][1], arr_p[j][0] - arr_p[i][0]);
    44             Aj[m].angle = k - tep;  Aj[m++].Judge = true;
    45             Aj[m].angle = k + tep;  Aj[m++].Judge = false;
    46         }
    47         sort(Aj, Aj + m, Cmp);
    48         int sum = 1;
    49         for (int k = 0; k < m; k++) {
    50             if (Aj[k].Judge)  {
    51                 sum++;
    52                 ans = (ans > sum) ? ans : sum;
    53             }
    54             else { sum--; }
    55         }
    56     }
    57     return ans;
    58 }
    59 
    60 int main()
    61 {
    62     //freopen("input.txt", "r", stdin);
    63     while (scanf("%d", &N) && N) {
    64         for (int i = 0; i < N; i++) {
    65             scanf("%lf %lf", &arr_p[i][0], &arr_p[i][1]);
    66         }
    67         printf("%d
    ", Solve(1.0));
    68     }
    69     return 0;
    70 }


  • 相关阅读:
    Python2 和 Python3的区别 更新中
    CentOS下图形界面安装_Orcaale 11g
    Nmap_使用介绍
    shell_innobackup增量备份步骤
    shell_跳板机推送公钥
    shell_clean_log
    shell_xtrabackup_backup_mysql
    gitlab免密登录
    gitlab安装与部署
    git合并分支
  • 原文地址:https://www.cnblogs.com/shijianming/p/4140836.html
Copyright © 2020-2023  润新知