题目1[NOIP-2015]
题目来源:https://nanti.jisuanke.com/t/T2028
算法思想
1.求最短距离的最大值,果断二分,注意这里将起点,终点都看作石头
1 2 3
| for(int i=1; i<=n; i++) scanf("%d", &a[i]); a[n+1]=l;
|
2.判断最短距离middle是否可行时,遍历数组,若两两距离小于middle,石头移走++cnt
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| int lower_bound(int low, int high) { int ans; while(low<=high) { int middle; middle= (low+high)>> 1; if(judge(middle)) { ans= middle; low= middle+1; } else high=middle-1; } return ans; }
|
1 2 3 4 5 6 7 8 9 10 11 12
| bool judge(int x) { int count= 0, now=0; for(int i=1; i<=n; i++) { if(a[i]- a[now]< x) count++; else now= i; } return count <= m; }
|
题目2[POJ-2456]
题目来源:https://vjudge.net/problem/POJ-2456
算法思想
1.同样求最短距离最大值,无需增加起点终点,注意要排序
2.选择奶牛所在位置,即上题确定石头的位置,那么记录空位置,即上题需要移走的石头数
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| bool judge(int x) { int now = 0, cnt = 0; for(int i = 1; i < n; ++i) { if(l[i] - l[now] < x) { ++cnt; } else now = i; } return cnt <= (n-m); }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| void solve() { sort(l, l+n); int low = 0, high = l[n-1] - l[0]+1, ans = -1; while(low <= high) { int middle = (low + high) >> 1; if(judge(middle)) { ans = middle; low = middle + 1; } else high = middle - 1; } printf("%d\n", ans); }
|