http://codeforces.com/gym/101028/problem/I
题意:给你n个洞,k个布条,问布条能贴到所有洞时的最小值。
题解:二分答案,因为答案越大就越容易满足条件。
技巧:两种judge写法:常规与upper_bound,嗯,就是有种可以upper_bound的感觉。
坑:VS提示upper_bound出错但是代码能ac Orz//_DEBUG_ERROR2("invalid iterator range", _File, _Line);百度不到为啥。。最后发现
pos = upper_bound(a + pos + 1, a + n + 1, a[pos] + mid - 1) - a;改成
pos = upper_bound(a + pos , a + n + 1, a[pos] + mid - 1) - a;就好了。有点意思
ac代码:正常写法
#define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<vector> #include<algorithm> #include<stdio.h> using namespace std; const int maxn = 1e5 + 5; int a[maxn]; int n, k; bool judge(int x) { int p = 0, cnt = 0; for (int i = 1; i <= n; i++) { if (p < a[i]) { cnt++; p = a[i] + x - 1; if (cnt == k) { if (p >= a[n])return 1; else return 0; } if (p >= a[n])return 1; } } return 0; } int main() { int t; cin >> t; while (t--) { cin >> n >> k; for (int i = 1; i <= n; i++) { scanf("%d", &a[i]); } int l = 1, r = a[n]; int mid; while (l <= r) { mid = l + r >> 1; if (!judge(mid)) l = mid+1; else r = mid-1; } cout << l << endl; } }
简化版:
#define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<vector> #include<algorithm> #include<stdio.h> using namespace std; const int maxn = 1e5 + 5; int a[maxn]; int n, k; bool judge(int x) { int pos = 1, cnt = 0; for (int i = 1; i <= k; i++) { pos = upper_bound(a + pos + 1, a + n + 1, a[pos] + x - 1) - a; } if (pos > n)return 0; return 1; } int main() { int t; cin >> t; while (t--) { cin >> n >> k; for (int i = 1; i <= n; i++) { scanf("%d", &a[i]); } int l = 1, r = a[n]; int mid; while (l <= r) { mid = l + r >> 1; int pos = 1; for (int i = 1; i <= k; i++) { pos = upper_bound(a + pos + 1, a + n + 1, a[pos] + mid - 1) - a; } if (pos>n) r = mid - 1; else l = mid + 1; } cout << l << endl; } }