[UVA714]Copying Books(二分)

wa了好多次,把sum的int改成long long就ac了,贼坑……

#include <bits/stdc++.h>

using namespace std;

const int maxn = 500 + 20;

int v[maxn];
int m;
int k;
int cut[maxn];      //分割线的位置

int ok(long long mid) {
    long long sum = 0;
    int cnt = 1;
    for(int i = m - 1; i >= 0; i--) {
        if (sum + v[i] > mid) {
            cnt++;       
            sum = v[i];
            if (cnt > k) return 0;
        }
        else sum += v[i];
    }
    return 1;
}

void cut_them(long long maxsum) {
    memset(cut, 0, sizeof(cut));
    long long sum = 0; 
    int cnt = 1;
    for(int i = m - 1; i >= 0; i--) {
        if (sum + v[i] > maxsum) {sum = v[i]; cut[i] = 1; cnt++; }
        else sum += v[i];
        if (k - cnt == i + 1) {
            for (int j = 0; j <= i; j++)
                cut[j] = 1;
            break;
        }
    }
}

void print() {
    for(int i = 0; i < m - 1; i++) {
        printf("%d ", v[i]);
        if (cut[i]) printf("/ ");
    }
    cout << v[m-1] << endl;
}

int main() {
    //freopen("input.txt", "r", stdin);
    int N;
    cin >> N;
    while(N--) {
        cin >> m >> k;
        long long left = -1;
        long long sum = 0;
        for(int i = 0; i < m; i++) {
            cin >> v[i];
            sum += v[i];
            if (v[i] > left) left = v[i];
        }
        long long right = sum; 
        while(right >= left) {
            long long mid = left + (right - left) / 2;  
            if (ok(mid)) 
                right = mid - 1;  
            else 
                left = mid + 1;

        }
        cut_them(left);
        print();
    }

    return 0;
}

猜你喜欢

转载自blog.csdn.net/sunmaoxiang/article/details/80573011