ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

洛谷P4343 [SHOI2015]自动刷题机

2021-05-18 16:05:13  阅读:177  来源: 互联网

标签:acc 洛谷 int P4343 long mid SHOI2015 include check


解题报告

注意到一个性质(当然不注意到一般也能想到): 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;
}

标签:acc,洛谷,int,P4343,long,mid,SHOI2015,include,check
来源: https://www.cnblogs.com/handwer/p/14781341.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有