第一道独立做出来的绿题祭(虽然花了我将近一个小时)
这是一道二分题目
1.为了方便:
因为这道题没有明确的规定抄书时间(反正不影响结果),所以我们不妨假设一个人抄一页需要1分钟。
2.确定二分范围
确定一下二分的范围:
最优情况:每个人都只抄一本,需要的时间为页数最大的那一本所需时间。
最坏情况:一个人要把所有书抄完,需要的时间为所有书加在一起的时间。
所以二分的范围就是从最大值到和。
3.核心代码
然后二分函数开始验证,注意验证的是当只给那么多时间的时候这些人可不可以完成抄写任务。二分的地方很简单,主要的部分其实是输出答案那一部分和 c h e c k check check函数。
首先先来看输出答案那一部分。
注意题目中的一句话:
如果有多解,则尽可能让前面的人抄写少的页数。
定义 l l l为需要的最小时间(也就是二分出来的答案)。
因为要求让前面的人抄得尽量少,意思就是说让后面的人抄得尽量多(这个点一定要倒着想,如果是从前到后的话需要搜索,这样会TLE)。那么就写一个循环,只要这个人现在抄的时间不超过 l l l,就让他一直抄,直到再加上一个就会超过为止,这样就可以保证后面的人抄得最多。
打一个有注释的代码(输出部分):
int flag=n,c=0;//flag代表目前拿到的书的编号,c代表现在这个人抄的时间
for(int i=k;i>=1;i--){
//枚举每一个人,要倒着枚举
while(c+a[flag]<=l&&flag){
//可以继续抄且有书可抄
c+=a[flag];//这个人抄的时间增加
flag--;//枚举下一本书
}
s[i]=flag+1;//这个人抄完了,存一下开始的编号
c=0;//清空时间
}
for(int i=1;i