hdu4932 Miaomiao's Geometry
这是一道搜索题,我们很容易得到目标值的上下界,然后就只能枚举了。
就是将x轴上的点排序之后从左到右依次考察每个点,每个点要么在线段的左端点,要么在线段的右端点。
点编号从0到n-1,从编号为1的点开始,在枚举的过程中不断压缩上界,有一种情况需要特别讨论,即哪种一条线段恰好覆盖相邻两个点的。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <map> 5 #include <string> 6 #include <vector> 7 #include <set> 8 #include <cmath> 9 #include <ctime> 10 #pragma comment(linker, "/STACK:102400000,102400000") 11 #define lson (u << 1) 12 #define rson (u << 1 | 1) 13 #define rep(i, a, b) for(i = a; i < b; i++) 14 #define reps(i, a, b, c) for(i = a; i < b; i += c) 15 #define repi(i, a, b) for(i = a; i >= b; i--) 16 #define cls(i, j) memset(i, j, sizeof i) 17 using namespace std; 18 typedef __int64 ll; 19 const double eps = 1e-6; 20 const double pi = acos(-1.0); 21 const int maxn = 1e5 + 10; 22 const int maxm = 1050; 23 const int inf = 0x3f3f3f3f; 24 const ll linf = 0x3fffffffffffffff; 25 const ll mod = 1e9 + 7; 26 27 double a[55]; 28 int n; 29 double maxi, mini; 30 31 double dfs(int u, int pre, double limit, int fixed){ 32 //printf("%d %d\n",u, pre); 33 if(u >= n - 1) return limit; 34 if(limit <= mini) return mini; 35 double to_left = a[u] - a[pre]; 36 double to_right = a[u + 1] - a[u]; 37 double tem; 38 if(fixed){ 39 if(to_left >= limit) return dfs(u + 1, u, limit, 1); 40 if(to_right >= 2 * limit || to_right == limit) return dfs(u + 2, u + 1, limit, 1); 41 if(to_right > limit) return dfs(u + 1, u + 1, limit, 1); 42 if(to_right < limit) return mini; 43 } 44 if(to_left >= limit) return dfs(u + 1, u, limit, 0); 45 double tem1 = dfs(u + 1, u, to_left, 0); 46 double tem2 = mini; 47 if(to_right >= 2 * limit) tem2 = dfs(u + 2, u + 1, limit, 0); 48 else{ 49 if(to_right <= limit) tem2 = dfs(u + 2, u + 1, to_right, 1); 50 double tem3 = mini; 51 if(limit >= to_right / 2) tem3 = dfs(u + 2, u + 1, to_right / 2, 0); 52 tem2 = max(tem2, tem3); 53 tem3 = dfs(u + 1, u + 1, min(to_right, limit), 0); 54 tem3 = max(tem2, tem3); 55 if(limit < to_right / 2) tem3 = dfs(u + 2, u + 1, limit, 0); 56 tem2 = max(tem2, tem3); 57 } 58 return max(tem1, tem2); 59 } 60 61 int main(){ 62 // freopen("in.txt", "r", stdin); 63 int T; 64 scanf("%d", &T); 65 while(T--){ 66 scanf("%d", &n); 67 int i; 68 rep(i, 0, n) scanf("%lf", &a[i]); 69 sort(a, a + n); 70 a[n] = 0; 71 mini = (double)linf; 72 rep(i, 1, n) mini = min(mini, a[i] - a[i - 1]); 73 maxi = (double)linf; 74 rep(i, 1, n - 1) maxi = min(maxi, max(a[i + 1] - a[i], a[i] - a[i - 1])); 75 double ans = dfs(1, 0, maxi, 0); 76 printf("%.3f\n", ans); 77 } 78 return 0; 79 }