1. 程式人生 > >菜鳥上路 杭電OJ 1007 求平面上兩點之間最短距離--分而治之以及關鍵點的考慮

菜鳥上路 杭電OJ 1007 求平面上兩點之間最短距離--分而治之以及關鍵點的考慮

Quoit Design


Problem Description Have you ever played quoit in a playground? Quoit is a game in which flat rings are pitched at some toys, with all the toys encircled awarded.
In the field of Cyberground, the position of each toy is fixed, and the ring is carefully designed so it can only encircle one toy at a time. On the other hand, to make the game look more attractive, the ring is designed to have the largest radius. Given a configuration of the field, you are supposed to find the radius of such a ring.

Assume that all the toys are points on a plane. A point is encircled by the ring if the distance between the point and the center of the ring is strictly less than the radius of the ring. If two toys are placed at the same point, the radius of the ring is considered to be 0.

Input The input consists of several test cases. For each case, the first line contains an integer N (2 <= N <= 100,000), the total number of toys in the field. Then N lines follow, each contains a pair of (x, y) which are the coordinates of a toy. The input is terminated by N = 0.

Output For each test case, print in one line the radius of the ring required by the Cyberground manager, accurate up to 2 decimal places. 

Sample Input
2
0 0
1 1
2
1 1
1 1
3
-1.5 0
0 0
0 1.5
0

Sample Output
0.71
0.00
0.75

Author CHEN, Yue
Source
Recommend JGShining      說實話,這篇文章什麼意思,我看了半天都沒有看懂!不過這不影響做題,這道題實際上就是要求一堆座標裡最短的座標之間的距離的1/2.     具體演算法在《程式設計之美》中講得很詳細!




  程式碼如下: [cpp] view plain copy  
print
?在CODE上檢視程式碼片派生到我的程式碼片
  1. /* 
  2. *最近點對的問題 
  3. */
  4. #include <iostream>
  5. #include <algorithm>
  6. #include <cmath>
  7. usingnamespace std;  
  8. constint SIZE = 100005;  
  9. constint L = -1;  
  10. constint R = 1;  
  11.  typedefstruct
  12. {  
  13.     int index;    
  14.     double x;  
  15.     double y;   /*用於記錄座標點*/
  16. }coord;  
  17. coord num[SIZE], c[SIZE]/*用作輔助陣列*/
    ;  
  18. double getDistance(coord &bi1, coord &bi2)  /*求得兩點之間的距離*/
  19. {  
  20.     return sqrt(pow(bi1.x - bi2.x, 2.0) + pow(bi1.y - bi2.y, 2.0));  
  21. }  
  22. bool cmpx(coord &bi1, coord &bi2)  
  23. {  
  24.     if (bi1.x == bi1.x)  
  25.         return bi1.y < bi2.y;  
  26.     else
  27.     return bi1.x < bi2.x;  
  28. }  
  29. bool cmpy(coord &bi1, coord &bi2)  
  30. {  
  31.     if (bi1.y == bi2.y)  
  32.         return bi1.x < bi2.x;  
  33.     else
  34.         return bi1.y < bi2.y;  
  35. }  
  36. inlinedouble min(double &bi1, double &bi2, double &bi3)  
  37. {  
  38.     double minLength;  
  39.     minLength = bi1 > bi2 ? bi2 : bi1;  
  40.     minLength = minLength > bi3 ? bi3 : minLength;  
  41.     return minLength;  
  42. }  
  43. inlinedouble minDist(double &bi1, double &bi2)  
  44. {  
  45.     if (bi1 > bi2)  
  46.         return bi2;  
  47.     return bi1;  
  48. }  
  49. double divide_conquer(int low, int high) /*分治法求最小距離*/
  50. {  
  51.     double dis;  
  52.     int count = high - low;  
  53.     if (count == 0)  
  54.     {  
  55.         return 0;  
  56.     }  
  57.     elseif (count == 1)  /*兩個數*/
  58.     {  
  59.         dis = getDistance(num[low], num[high]);  
  60.     }  
  61.     elseif (count == 2)  /*三個數*/
  62.     {  
  63.         double temp1, temp2, temp3;  
  64.         temp1 = getDistance(num[low], num[low + 1]);  
  65.         temp2 = getDistance(num[low + 1], num[high]);  
  66.         temp3 = getDistance(num[low], num[high]);  
  67.         dis = min(temp1, temp2, temp3);  
  68.     }  
  69.     else/*大於三個數的情況*/
  70.     {  
  71.         double leftmin, rightmin, min;  
  72.         int mid = (low + high) / 2;  
  73.         int p = 0;  
  74.         int i, j;  
  75.         leftmin = divide_conquer(low, mid);  /*求得左邊部分的最小值*/
  76.         rightmin = divide_conquer(mid + 1, high);  /*求得右邊部分的最小值*/
  77.         dis = minDist(leftmin, rightmin);  
  78.         /*下面從所有座標點中找出所有x在leftCoord到rightCoord之間的點*/
  79.         for (i = low; i <= mid; i++)  
  80.         {  
  81.             double leftCoord = num[mid].x - dis;  
  82.             if (num[i].x >= leftCoord)  
  83.             {  
  84.                 c[p].index = L;  /*標識屬於左邊部分*/
  85.                 c[p].x = num[i].x;  
  86.                 c[p].y = num[i].y;  
  87.                 p++;  
  88.             }  
  89.         }  
  90.         for ( ; i <= high; i++)  
  91.         {  
  92.             double rightCoord = num[mid].x + dis;  
  93. 相關推薦

    上路 OJ 1007 平面兩點之間短距離--以及關鍵點考慮

    Quoit Design Problem Description Have you ever played quoit in a playground? Quoit is a game in which flat rings are pitched a

    分治演算法五(最近點對---OJ 1007 Quoit Design)

    1、問題描述 即給定座標系上N個點,找到距離最短的兩個點。 2、思路解析 ----->如果直接利用兩兩點比較的話,複雜度太高,為O(n^2),會導致超時 ----->簡化問題:考慮一維數軸上點的情況,如果對這些點排序O(nlgn),那麼最後只需要用O(n)時間

    oj 奇數的乘積

    col 杭電 can while pre n) style amp printf #include <stdio.h> #include <stdlib.h> int main() { int i,n,a; int

    oj 數列的和

    i++ 杭電oj lib tom 平方根 整數 () ali stdlib.h Problem Description 數列的定義如下:數列的第一項為n,以後各項為前一項的平方根,求數列的前m項的和。 Input 輸入數據有多組,每組占一行,由兩個整數n(

    上路如何編寫python註冊模塊

    當我 sans 切割 username 輸入 see put 註冊 1-1 我們先來確定下需求: 寫一個註冊的程序,輸入username,passwd,confirmpasswd 註冊成功之後,提示註冊成功,程序退出,要求用戶名不能重復 錯誤次數也是3次一.需求分析:需求

    近幾年OJ大型比賽題目合集【更新到2017年10月】

    杭電 網絡賽 2016年 fin 區域賽 現場賽 2015年 font strong 2017年: 區域賽網絡賽 6194~6205 6206~6216 2016年: 區域賽網絡賽 5868~5877 5878~5891 5892~5901 區域賽

    上路,nfs

    地址 grep tab utils ins status service mct sha -----01客戶端IPtables -FIPtables -Xsetenforce 0yum install nfs-utilsshowmout -e 02的ip地址:/

    oj 1106

    total rip memory spa 除開 scan long tdi else 排序 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Su

    sincerit-oj 1237 簡單計算器

    1237 簡單計算器 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 26856 Accepted Submission(s): 9

    【ACM】OJ 2015

        #include <iostream> using namespace std; int main () { int count,sum,i,j,m,n; while(scanf("%d%d",&m,&n)==2) {

    【ACM】OJ 2090

    題目中給出的四捨五入的條件可以忽略不計了,因為提交的程式沒有考慮四捨五入,照樣AC了 printf("%.1lf\n",sum); AC程式碼: 寫的有點複雜了,其實不用定義結構體也可以。  #include<iostream> #include <c

    【ACM】OJ 1284(待更)

    #include<iostream> using namespace std; int main(){ int n; while(cin>>n){ int ans=0; for(int i=0;i<=n/3;i++){ /

    【ACM】OJ 1013

    WA程式碼 輸入很大的數的時候會輸出“-1”,所以考慮用字元陣列來儲存輸入的資料。 #include <iostream> #include <cstring> #include <cstdio> using namespace std; lon

    【ACM】OJ 1076

    陣列要開的大一些,一開始陣列只開到10000+5,就顯示了錯誤的資料 AC程式碼:  #include <iostream> #include <cstring> using namespace std; const int maxn = 1000

    【ACM】OJ 2552

    本來還查了atan 和 atan2 的用法,結果總是WA 看了解析之後才知道原來是要公式推導,最後得出所求的式子是一個等式,結果為1。 所以,以後出類似與數學公式的題,可能是要手算推到,在輸出特定的結果。(長見識!之前也遇到過,突然想起來) WA程式碼: #include <

    【ACM】OJ 1181

    http://acm.hdu.edu.cn/showproblem.php?pid=1181 DFS搜尋(遞迴函式) #include <iostream> #include <cstdio> #include <cstring> #include &

    oj蟠桃

    C++ #include<iostream> using namespace std; int main() { int n; int m=1; //桃子數量 while(cin>>n) { for(int i

    oj水仙花數

    Problem Description 春天是鮮花的季節,水仙花就是其中最迷人的代表,數學上有個水仙花數,他是這樣定義的: “水仙花數”是指一個三位數,它的各位數字的立方和等於其本身,比如:153=13+53+3^3。 現在要求輸出所有在m和n範圍內的水仙花數。 I

    oj--2031

    import java.util.Scanner; public class Main {  public static void main(String[] args){   Scanner scanner = new Scanner(System.in);  

    oj-Vowel Counting

    #include<stdio.h> #include<string.h> #include<stdlib.h> int main() { int T,first=1; char s[51],c; scanf_s("%d", &T); while (