【luoguP4343】自动刷题机
题目
题目背景
曾经发明了信号增幅仪的发明家 SHTSC 又公开了他的新发明:自动刷题机——一种可以自动 AC 题目的神秘装置。
题目描述
自动刷题机刷题的方式非常简单:首先会瞬间得出题目的正确做法,然后开始写程序。每秒,自动刷题机的代码生成模块会有两种可能的结果:
1.写了 x 行代码
2.心情不好,删掉了之前写的 y 行代码。(如果 y 大于当前代码长度则相当于全部删除。)
对于一个 OJ,存在某个固定的正整数长度 n,一旦自动刷题机在某秒结束时积累了大于等于 n 行的代码,它就会自动提交并 AC 此题,然后新建一个文件(即弃置之前的所有代码)并开始写下一题。SHTSC 在某个 OJ 上跑了一天的自动刷题机,得到了很多条关于写代码的日志信息。他突然发现自己没有记录这个 OJ 的 \(n\) 究竟是多少。所幸他通过自己在 OJ 上的 Rank 知道了自动刷题机一共切了 \(k\) 道题,希望你计算 \(n\) 可能的最小值和最大值。
输入格式
第一行两个整数 \(l,k\),表示刷题机的日志一共有 \(l\) 行,一共了切了 \(k\) 题。
接下来 \(l\) 行,每行一个整数 \(x_i\),依次表示每条日志。若 \(x_i\)≥0,则表示写了 \(x_i\)行代码,若 \(x_i\)<0,则表示删除了 -\(x_i\)行代码。
输出格式
输出一行两个整数,分别表示 \(n\) 可能的最小值和最大值。
如果这样的\(n\)不存在,请输出一行一个整数 \(−1\)。
数据范围
对于 20% 的数据,保证 \(l≤10\)
对于 40% 的数据,保证 \(l≤100\)
对于 60% 的数据,保证 \(l≤2×10^3\)
对于 100% 的数据,保证 $1≤l≤\(10^5\)
链接:
https://www.luogu.com.cn/problem/P4343
思路
初看想法
第一眼看到这个题目的数据范围,显然不是用暴力求解,先试试20%数据
20%数据
20%数据显然可以通过枚举n嘛,把n枚举出来再看看能否切掉k道题目就可以了。等等……枚举n?
100%数据
既然要枚举n,那完全可以用二分来枚举。这不就是一题二分答案嘛,只不过要求一个最大值一个最小值,两次二分就能解决了。
code:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n,k;
ll a[100000+10];
ll pd(ll x){
ll sum=0,t=0;
for(int i=1;i<=n;i++){
sum+=a[i];
if(sum<0) sum=0;
if(sum>=x) t++,sum=0;
}
return t;
}
int main(){
cin>>n>>k;
for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
ll left=1,right=1e14;
ll minans=-1,maxans=-1;
while(left<=right){
ll mid=(left+right)/2;
ll d=pd(mid);
if(d==k) minans=mid,right=mid-1;
else if(d<k) right=mid-1;
else left=mid+1;
}
left=1,right=1e14;
while(left<=right){
ll mid=(left+right)/2;
ll d=pd(mid);
if(d==k) maxans=mid,left=mid+1;
else if(d<k) right=mid-1;
else left=mid+1;
}
if(minans==-1&&maxans==-1) cout<<-1;
else
cout<<minans<<' '<<maxans;
}

浙公网安备 33010602011771号