• 洛谷P4343 [SHOI2015]自动刷题机


    解题报告

    注意到一个性质(当然不注意到一般也能想到): n 越大,能过的题就越少。这是一个单调的性质。

    考虑二分这个 n,最大值和最小值分开做都一样的。这里讲最小值。

    check 函数很好想,传进去当前二分的 n,然后按题意模拟,获得实际 AC 数,和给定的 AC 数对比一下确定是高了还是低了,然后更新边界即可。

    最大值最小值更新边界的区别可以手玩验证。原则是:求最小值就尽量调低,求最大值就尽量调高。

    代码实现

    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <vector>
    #include <string>
    #include <set>
    #include <map>
    
    // 性质:N 越大,能过的题越少 
    
    const int MAXL = 1e5 + 10;
    
    int l; long long int k;
    long long int mnans = -1, mxans;
    long long int logg[MAXL];
    
    long long int check(long long int fn) {
    	long long int exist = 0, acc = 0;
    	for (int i = 1; i <= l; ++i) {
    		exist = std::max(exist + logg[i], 0ll);
    		if (exist >= fn) { ++acc; exist = 0; }
    	}
    	return acc; // 过题数 
    }
    
    int main() {
    	scanf("%d %lld", &l, &k); 
    	for (int i = 1; i <= l; ++i) scanf("%lld", logg + i);
    	long long int l = 1, r = 0x7f7f7f7f7f7f7f7f;
    	while (l <= r) { // min
    		long long int mid = (l + r) >> 1ll;
    		long long int acc = check(mid);
    		if (acc <= k) {
    			r = mid - 1;
    			if (acc == k) mnans = mid; // 满足条件更新答案 
    		} else l = mid + 1;
    	} if (mnans == -1) {
    		puts("-1"); return 0;
    	}
    	l = 1, r = 0x7f7f7f7f7f7f7f7f;
    	while (l <= r) { // max
    		long long int mid = (l + r) >> 1ll;
    		long long int acc = check(mid);
    		if (acc >= k) {
    			l = mid + 1;
    			if (acc == k) mxans = mid;
    		} else r = mid - 1;
    	} printf("%lld %lld", mnans, mxans);
    	return 0;
    }
    
  • 相关阅读:
    loadrunder之脚本篇——action分类
    性能测试工具下载
    Loadrunder常见问题汇总(持续更新)
    python编程总结
    使用 rsync 同步
    mysql查询今天、昨天、7天、近30天、本月、上一月 数据
    vim配置
    shell 分割字符串存至数组
    变换莫测
    2014 10
  • 原文地址:https://www.cnblogs.com/handwer/p/14781341.html
Copyright © 2020-2023  润新知