1、POJ 3258 River Hopscotch
题意:给出小溪的长度L,给出河中石头数N和最多可移动的石头数M,使得每两颗相邻石头、起点与第一颗石头、终点与最后一颗石头之间的最小距离最大。
思路:二分最小距离,然后把间距小于该距离的石头移除,如果移除的石头数大于M,说明该距离太大,否则可以尝试增大该距离。
1 #include<iostream> 2 #include<algorithm> 3 using namespace std; 4 int L, N, M; 5 int st, ed; 6 const int maxn = 50005; 7 int Rocks[maxn]; 8 bool Judge(int dis) 9 { 10 int rmvrocks = 0; 11 int tdis = 0; 12 int refpos = 0; 13 int tnumrocks = 0; 14 for (int i = 0; i < N;) 15 { 16 tnumrocks = 0; 17 while (i<N&&Rocks[i] - refpos < dis) tnumrocks++,i++; 18 rmvrocks += tnumrocks; 19 refpos = Rocks[i]; 20 i++; 21 } 22 if (tnumrocks == 0 && L - Rocks[N - 1] < dis) rmvrocks++; 23 if (rmvrocks > M) return false; 24 else return true; 25 } 26 int main() 27 { 28 while (cin >> L) 29 { 30 cin >> N >> M; 31 for (int i = 0; i < N; i++) cin >> Rocks[i]; 32 sort(Rocks, Rocks + N); 33 int mindis = Rocks[0]; 34 for (int i = 1; i < N; i++) 35 if (Rocks[i] - Rocks[i - 1] < mindis) mindis = Rocks[i] - Rocks[i - 1]; 36 if (L - Rocks[N - 1] < mindis) mindis = L - Rocks[N - 1]; 37 int l = mindis, r = L; 38 while (l <= r) 39 { 40 int mid = (l + r) / 2; 41 if (Judge(mid)) l = mid + 1; 42 else r = mid - 1; 43 } 44 cout << r << endl; 45 } 46 return 0; 47 }