Document directory
- The design process is divided into three phases
I haven't done any questions for a long time, mainly because I am busy at work and have to spend some time with my girlfriend. However, algorithms are a little hobby of my own, and I still want to do my exercises if I have time, just change your mind and take a rest! Haha!
Next question: first, we will briefly introduce the divide-and-conquer algorithm: the design process is divided into three phases.
-Divide: the entire problem is divided into multiple sub-problems-Conquer: solving each sub-problem (recursively calling the algorithm being designed)-combine: Merge the sub-problem solutions to form a solution to the original problem.
For example
Give you n points and find the shortest distance between the points.
Algorithm Design
This topic is to use the above grouping algorithm. Divide all vertices into two parts: left and right. The shortest distance is either left or right or cross border.
Then we can recursion. If there is only one vertex left, a value over 10000 will be returned. If there are only two vertices, we can directly find the distance.
Then, if n points are divided into two parts, the minimum value on the left and the minimum value on the right are obtained recursively, And the min value on the right is obtained. Then, the distance between the points across the boundary is enumerated, at this time, we only need to take the distance between the two sides Less Than Min, because the distance greater than min is meaningless to our results.
Here I made some optimization, that is, why the loop in the Code is smaller than I + 7, rather than CNT. In fact, CNT is also a waste of time. In fact, we can find all the points with distance to the boundary and enumerate the distance between them directly. We can compare it with Min and return the minimum value.
How to optimize it is proved as follows: 1. situation description
2. Search for points 3. Method 4. A maximum of six such points 5. Pigeon nest principles
Code:
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <math.h>struct POINT {double x,y;}point[10010],temp[10010];double dis(struct POINT p1, struct POINT p2){return sqrt((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y));}int cmp(const void * a, const void * b){struct POINT * c = (struct POINT *)a;struct POINT * d = (struct POINT *)b;if (c->x != d->x){return c->x > d->x;}elsereturn c->y > d->y;}int cmp1(const void * a, const void * b){struct POINT * c = (struct POINT *)a;struct POINT * d = (struct POINT *)b;if (c->y != d->y){return c->y > d->y;}elsereturn c->x > d->x;}double findMin(int l, int r){if (l == r){return 10010;}if (l == r - 1){return dis(point[l], point[r]);}double tmp1 = findMin(l,(l + r) >> 1);double tmp2 = findMin(((l + r) >> 1) + 1, r);double Mindis,tmp, mid;mid = point[(l + r) >> 1].x;/*mid = (point[l].x + point[r].x) / 2.0;*/int i,j,cnt = 0;if (tmp1 < tmp2){Mindis = tmp1;}elseMindis = tmp2;for (i = l; i <= r; ++ i){if (fabs(point[i].x - mid) < Mindis){temp[cnt ++] = point[i];}}qsort(temp, cnt, sizeof(temp[0]), cmp1);for (i = 0; i < cnt - 1; ++ i){/*for (j = i + 1; j < cnt; ++ j)*/for (j = i + 1; j < i + 7 && j < cnt; ++ j){tmp = dis(temp[i], temp[j]);if (tmp < Mindis){Mindis = tmp;}}}return Mindis;}int main(){int n,i,j;double minDis;while (scanf("%d", &n)==1 && n){for (i = 0; i < n; ++ i){scanf("%lf%lf", &point[i].x, &point[i].y);}qsort(point, n, sizeof(point[0]), cmp);minDis = findMin(0, n-1);if (minDis > 10000){printf("INFINITY\n");}elseprintf("%.4lf\n", minDis);}return 0;}