hdu1007, 算法课的一个例子,计算几何和分治法。在hdu上ac了, zoj上死活过不了。
附代码:
1 /* 2 3 */ 4 #include <stdio.h> 5 #include <stdlib.h> 6 #include <string.h> 7 #include <math.h> 8 #define MAX 101000 9 10 typedef struct point 11 { 12 int id; 13 double x; 14 double y; 15 } POINT; 16 17 POINT sorted_x[MAX], sorted_y[MAX], sub_y[MAX]; 18 POINT split_y1[MAX],split_y2[MAX]; 19 int len_sub_y = 0, len = 0; 20 int len_split1 = 0, len_split2 = 0; 21 22 int comp_x(const void *a, const void *b) 23 { 24 POINT *aa = (POINT *)a; 25 POINT *bb = (POINT *)b; 26 return aa->x - bb->x; 27 } 28 29 int comp_y(const void *a, const void *b) 30 { 31 POINT *aa = (POINT *)a; 32 POINT *bb = (POINT *)b; 33 return bb->y - aa->y; 34 } 35 36 double cal_dist(POINT a, POINT b) 37 { 38 return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y)); 39 } 40 41 double min_distance(int left, int right, POINT *ptr, int len) 42 { 43 if (right - left + 1 <= 3) 44 { 45 // cal directly. 46 if (right - left + 1 == 2) 47 return cal_dist(sorted_x[left], sorted_x[right]); 48 else 49 { 50 double dis1 = cal_dist(sorted_x[left], sorted_x[left + 1]); 51 double dis2 = cal_dist(sorted_x[left], sorted_x[right]); 52 double dis3 = cal_dist(sorted_x[left + 1], sorted_x[right]); 53 double min = dis1 > dis2 ? dis2 : dis1; 54 return min > dis3 ? dis3 : min; 55 } 56 } 57 int mid = (left + right) / 2; 58 double mid_value = (sorted_x[mid].x + sorted_x[mid + 1].x) / 2; 59 60 POINT *ptr1 = (POINT *)malloc(sizeof(POINT) * (len / 2 + 10)); 61 POINT *ptr2 = (POINT *)malloc(sizeof(POINT) * (len / 2 + 10)); 62 63 //printf("\n%d\n", len); 64 int j, k; 65 j = k = 0; 66 for (int i = 0; i < len; i++) 67 { 68 //printf("\n(%d %d)\n", ptr[i].id, mid); 69 if (ptr[i].id <= mid && ptr[i].id >= left) 70 { 71 ptr1[j] = ptr[i]; 72 j++; 73 } 74 else 75 { 76 ptr2[k] = ptr[i]; 77 k++; 78 } 79 } 80 //printf("\n(%d %d)\n", mid - left + 1, j); 81 //printf("\n(%d %d)\n", right - mid, k); 82 double min1 = min_distance(left, mid, ptr1, mid - left + 1); 83 double min2 = min_distance(mid + 1, right, ptr2, right - mid); 84 double final = min1 < min2 ? min1 : min2; 85 86 free(ptr1); 87 free(ptr2); 88 len_sub_y = 0; 89 for (int i = 0; i < len; i++) 90 { 91 if (fabs(ptr[i].x - mid_value) <= final) 92 { 93 sub_y[len_sub_y] = ptr[i]; 94 len_sub_y++; 95 } 96 } 97 98 99 for (int i = 0; i < len_sub_y - 1; i++) 100 { 101 for (int j = i + 1; j < len_sub_y && j < i + 1 + 7; j++) 102 { 103 double tmp = cal_dist(sub_y[i], sub_y[j]); 104 if (tmp < final) 105 final = tmp; 106 } 107 } 108 return final; 109 } 110 111 int main() 112 { 113 int n; 114 while (1) 115 { 116 scanf("%d", &n); 117 len = n; 118 if (n == 0) 119 return 0; 120 for (int i = 0; i < n; i++) 121 scanf("%lf %lf", &sorted_x[i].y, &sorted_x[i].x); 122 qsort(sorted_x, n, sizeof(POINT), comp_x); 123 // for (int i = 0; i < n; i++) 124 // printf("%f ", sorted_x[i].x); 125 126 for (int i = 0; i < n; i++) 127 sorted_x[i].id = i; 128 129 memcpy(sorted_y, sorted_x, sizeof(POINT) * n); 130 qsort(sorted_y, n, sizeof(POINT), comp_y); 131 //for (int i = 0; i < n; i++) 132 //printf("%d (%f %f) ", sorted_y[i].id, sorted_y[i].x, sorted_y[i].y); 133 printf("%.2lf\n", min_distance(0, n - 1, sorted_y, n) / 2); 134 } 135 }