Gym - 101028I March Rain 二分

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;
    }

}

 

posted @ 2018-03-09 20:24  SuuTTT  阅读(305)  评论(0编辑  收藏  举报