2012-12-15 10:37:21Morris
[UVA][二分+貪婪] 11516 - WiFi
Problem B: WiFi
One day, the residents of Main Street got together and decided that they would install wireless internet on their street, with coverage for every house. Now they need your help to decide where they should place the wireless access points. They would like to have as strong a signal as possible in every house, but they have only a limited budget for purchasing access points. They would like to place the available access points so that the maximum distance between any house and the access point closest to it is as small as possible.Main Street is a perfectly straight road. The street number of each house is the number of metres from the end of the street to the house. For example, the house at address 123 Main Street is exactly 123 metres from the end of the street.
Input Specification
The first line of input contains an integer specifying the number of test cases to follow. The first line of each test case contains two positive integers n, the number of access points that the residents can buy, and m, the number of houses on Main Street. The following m lines contain the house numbers of the houses on Main Street, one house number on each line. There will be no more than 100 000 houses on Main Street, and the house numbers will be no larger than one million.Sample Input
1 2 3 1 3 10
Output Specification
For each test case, output a line containing one number, the maximum distance between any house and the access point nearest to it. Round the number to the nearest tenth of a metre, and output it with exactly one digit after the decimal point.Output for Sample Input
1.0
因為是整數座標,答案一定是落在 x.0 或者是 x.5。那我們全部換成整數運算即可。
二分搜答案,用 Greedy 去判定。
#include <stdio.h>
#include <algorithm>
#include <math.h>
using namespace std;
int A[100005];
int n, m, i, l, r, mm;
int greedy(int mm) {
static int cnt;
static int r;
cnt = 1;
r = A[0] + mm;
for(i = 0; i < m; i++) {
if(abs(r-A[i]) <= mm) {}
else {
cnt++;
if(cnt > n) return 0;
r = A[i] + mm;
}
}
return 1;
}
inline int ReadInt(int *x) {
static char c, neg;
while((c = getchar()) < '-') {if(c == EOF) return EOF;}
neg = (c == '-') ? -1 : 1;
*x = (neg == 1) ? c-'0' : 0;
while((c = getchar()) >= '0')
*x = (*x << 3) + (*x << 1) + c-'0';
*x *= neg;
return 1;
}
int main() {
scanf("%*d");
while(scanf("%d %d", &n, &m) == 2) {
for(i = 0; i < m; i++)
ReadInt(&A[i]), A[i] *= 2;
sort(A, A+m);
l = 0, r = (A[m-1]-A[0])/2;
while(l <= r) {
mm = (l+r)/2;
if(greedy(mm)) {
r = mm-1;
} else
l = mm+1;
}
printf("%.1lf\n", (r+1)/2.0);
}
return 0;
}