首页 > 其他分享 >P4343 [SHOI2015] 自动刷题机(最详细版本 通俗易懂)

P4343 [SHOI2015] 自动刷题机(最详细版本 通俗易懂)

时间:2024-10-18 13:52:18浏览次数:3  
标签:代码 LL mid P4343 SHOI2015 切题 check 刷题

题目背景

曾经发明了信号增幅仪的发明家 SHTSC 又公开了他的新发明:自动刷题机——一种可以自动 AC 题目的神秘装置。

题目描述

自动刷题机刷题的方式非常简单:首先会瞬间得出题目的正确做法,然后开始写程序。每秒,自动刷题机的代码生成模块会有两种可能的结果:

1.写了 x 行代码
2.心情不好,删掉了之前写的 y 行代码。(如果 y 大于当前代码长度则相当于全部删除。)

对于一个 OJ,存在某个固定的正整数长度 n,一旦自动刷题机在某秒结束时积累了大于等于 n 行的代码,它就会自动提交并 AC 此题,然后新建一个文件(即弃置之前的所有代码)并开始写下一题。SHTSC 在某个 OJ 上跑了一天的自动刷题机,得到了很多条关于写代码的日志信息。他突然发现自己没有记录这个 OJ 的 n 究竟是多少。所幸他通过自己在 OJ 上的 Rank 知道了自动刷题机一共切了 k 道题,希望你计算 n 可能的最小值和最大值。

输入格式

第一行两个整数 l,k,表示刷题机的日志一共有 l 行,一共了切了 k 题。

接下来 l 行,每行一个整数 xi,依次表示每条日志。若 xi≥0,则表示写了 xi​ 行代码,若 xi<0,则表示删除了 −xi​ 行代码。

输出格式

输出一行两个整数,分别表示 n 可能的最小值和最大值。
如果这样的 n 不存在,请输出一行一个整数 −1。

输入输出样例

输入 #1

4 2
2
5
-3
9

输出 #1

3 7

说明/提示

数据规模与约定
  • 对于 20% 的数据,保证 l≤10;
  • 对于 40% 的数据,保证 l≤100 ;
  • 对于 60% 的数据,保证l≤2×103;
  • 对于 100% 的数据,保证 1≤l≤105,−109≤xi≤109。

解题思路(小tips)

本题的逻辑思维较简单 但需要二分本身具有足够的认识 否则容易混乱 搞不清出如何迭代

check函数的内层逻辑也很简单 就是直接模拟 返回切题的计数即可

所以本题最大的难点就在于两次二分的过程

当然也有的题解是进行一次二分 然后直接递增或递减 检查每一个数是否满足check 知道找到不符合即另一个边界即可 但因为是二分的专项练习 所以我们这里只提供两次二分的思路解析和代码

具体的代码思路部分为

while(l<=r){
		LL mid=l+r>>1;
		if(check(mid)<m) r=mid-1;
		else if(check(mid)>m) l=mid+1;
		else ans1=mid,r=mid-1;
	}
	

这么写的思路 也很简单 :切题数不足 则是阈值过大 直接缩小右边界 从而减小下次迭代的mid答案阈值 反之亦然 恰好相等时即找到答案

但是也有读者说 我的二分模板是这样的

为什么最终答案不同或者只能找到一个边界

while(l<r){
		LL mid=l+r>>1;
		if(check(mid)<=m) r=mid;
		else l=mid+1;
	}

这里其实是因为 题目中要求的是切题数必须恰好等于k的 交题阈值的最大最小值 而上面的模板在寻找时的边界是<= 或者>= 其实找到的是能够切题数>=m的最右答案 和切题数<=m的最左答案 而非=m时的最左最右答案

AC代码展示

如果觉得有用 就点赞+收藏 关注一下吧

#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N=1e5+5;
LL n,m,a[N];

LL check(LL x){
	LL sum=0,cnt=0;
	for(int i=1;i<=n;i++){
		sum+=a[i];
		if(sum<0) sum=0;
		if(sum>=x) cnt++,sum=0;
	}
	return cnt;
}

int main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++) cin>>a[i];
	LL l=1,r=1e15;
	LL ans1=-1; 
	while(l<=r){
		LL mid=l+r>>1;
		if(check(mid)<m) r=mid-1;
		else if(check(mid)>m) l=mid+1;
		else ans1=mid,r=mid-1;
	}
	
	cout<<ans1<<" ";
	if(ans1==-1) return 0;
	
	l=1,r=1e15;
	LL ans2=-1; 
	while(l<=r){
		LL mid=l+r>>1;
		if(check(mid)<m) r=mid-1;
		else if(check(mid)>m) l=mid+1;
		else ans2=mid,l=mid+1;
	}
	cout<<ans2<<endl;
	return 0;
}

标签:代码,LL,mid,P4343,SHOI2015,切题,check,刷题
From: https://blog.csdn.net/xingheyan/article/details/143051470

相关文章

  • 打卡信奥刷题(069)用C++工具信奥P11076[普及组/提高] 「FSLOI Round I」单挑
    「FSLOIRoundI」单挑题目背景Englishstatement.YoumustsubmityourcodeattheChineseversionofthestatement.小F和小S经常进行篮球单挑,但小S总是被盖帽。题目描述每次单挑的结果一定是小F获胜或者小S获胜,不存在平局的情况。由于小F和小S实......
  • 【刷题】东方博宜OJ 1136 - 输出m和n范围内的完全数(完美数)
    1136-输出m和n范围内的完全数(完美数)东方博宜OJ输入210输出6题解这题时间范围要注意,因数自定义函数不够优化会超时。#include<bits/stdc++.h>#definelonglongll;#defineunsignedlonglongull;usingnamespacestd;intf(intn){ intans=1; ......
  • Leetcode刷题. 贪心算法
    贪心算法:    比较传统的解释:将整个问题拆解为几个小问题,找到小问题的最优解,加起来就是整个问题的全局最优解。对于现在的我理解贪心就是一种感觉,给出证明很难,解题思路一般就是认真读题,发掘题目的条件,然后尝试给出算法。11.盛最多水的容器     一个显而易......
  • 力扣刷题_SQL50题
    高频SQL50题(基础版)-学习计划-力扣(LeetCode)全球极客挚爱的技术成长平台602.好友申请II:谁有最多的好友题目:编写解决方案,找出拥有最多的好友的人和他拥有的好友数目。生成的测试用例保证拥有最多好友数目的只有1个人。CreatetableIfNotExistsRequestAccepte......
  • 打卡信奥刷题(056)用C++工具信奥P10566[普及组/提高] 「Daily OI Round 4」Analysis
    「DailyOIRound4」Analysis题目描述小C的信息技术老师给小C布置了一项作业,作业内容如下:有一个字符串,包含大小写字母和数字。你可以把任意一个字符变成另外一个字符,设变化之前字符的ASCII码为a......
  • 软件开发----Java基础每日刷题(转载于牛客)
    1.        A 是抽象父类或接口, B , C 派生自 A ,或实现 A ,现在 Java 源代码中有如下声明:1. A a0=new A();2. A a1=new B();3. A a2=new C();问以下哪个说法是正确的?()A        第1行不能通过编译B        第1、2行能通......
  • leetcode 刷题day43动态规划Part12(115.不同的子序列、583. 两个字符串的删除操作、72.
    115.不同的子序列思路:这个题还是比较有难度的,问题s中有多少个t子序列可以转化为s字符串中有多少删除元素的方式,使s可以变成t。考虑动规五部曲。1、确定dp数组(dptable)以及下标的含义dp[i][j]:以i-1为结尾的s子序列中出现以j-1为结尾的t的个数为dp[i][j]。2、确定递推公式......
  • leetcode 刷题day42动态规划Part11(1143.最长公共子序列、1035.不相交的线、53. 最大子
    1143.最长公共子序列思路:718.最长重复子数组两个数组对应相同且连续,所以递推公式是dp[i-1][j-1]+1。最长公共子序列不要求连续但要求相对顺序,差别主要在于递推公式。对于该题主要有两大情况:text1[i-1]与text2[j-1]相同,text1[i-1]与text2[j-1]不相同。如果te......
  • 数据结构与算法篇(回溯&递归&分治 - 刷题篇)(目前一天图片上传太多加载不出来)(后续更新)
    目录1.没有重复项数字的全排列(中等)1.1.题目描述1.2解题思路1.3代码实现方法一:递归方法二:非递归版2.有重复项数字的全排列(中等)2.1.题目描述2.2.解题思路2.3.代码实现递归+回溯(推荐使用)3.岛屿数量(中等)3.1.题目描述3.2.解题思路3.3代码实现方法一:dfs......
  • 代码随想录刷题学习日记
    仅为个人记录复盘学习历程,解题思路来自代码随想录代码随想录刷题笔记总结网址:代码随想录替换数字给定一个字符串s,它包含小写字母和数字字符,请编写一个函数,将字符串中的字母字符保持不变,而将每个数字字符替换为number。提供参数:strings主要操作:将数组扩容到所有数字都......