zoukankan      html  css  js  c++  java
  • 洛谷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;
    }
    
  • 相关阅读:
    js字符串截取函数slice()、substring()、substr()
    js获取字符串最后一位方法
    支持xhr浏览器:超时设定、加载事件、进度事件
    深入理解ajax系列第一篇——XHR对象
    MySQL命令行操作
    nodejs中mysql用法
    大衍数列
    牌型种数
    加法变乘法
    三羊献瑞
  • 原文地址:https://www.cnblogs.com/handwer/p/14781341.html
Copyright © 2011-2022 走看看