bzoj4590[Shoi2015]自动刷题机

bzoj4590[Shoi2015]自动刷题机

题意:

有一种自动刷题机。每秒,有两种可能的结果:写了x行代码,或删掉了之前写的y行代码。(如果y大于当前代码长度则相当于全部删除。)一旦自动刷题机在某秒结束时积累了大于等于n行的代码,它就会自动AC一题,然后新建一个文件开始写下一题。知道共切了k道题。求n可能的最小值和最大值。操作数和k≤100000

题解:

由于n越小切题数越多,故二分n就行了。反思:没看到找不到要输出-1的要求,加上二分边界太小,wa了好几发QAQ~

代码:

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #define maxn 100010
 5 #define inc(i,j,k) for(int i=j;i<=k;i++)
 6 #define ll long long
 7 using namespace std;
 8 
 9 int n; ll k,opt[maxn],l,r,ansl,ansr;;
10 inline int read(){
11     char ch=getchar(); int f=1,x=0;
12     while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();} while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
13     return f*x;
14 }
15 ll check(ll x){
16     ll y=0,z=0; inc(i,1,n){z+=opt[i]; if(z<0)z=0; if(z>=x)y++,z=0;} return y;
17 }
18 int main(){
19     n=read(); k=(ll)read(); inc(i,1,n)opt[i]=(ll)read();
20     l=1; r=1e15; while(l<=r){ll mid=l+r>>1; if(check(mid)<=k)ansl=mid,r=mid-1;else l=mid+1;}
21     l=1; r=1e15; while(l<=r){ll mid=l+r>>1; if(check(mid)<k)r=mid-1;else ansr=mid,l=mid+1;}
22     if(check(ansl)!=k||check(ansr)!=k)printf("-1");else printf("%lld %lld",ansl,ansr);
23     return 0;
24 }

20160701

原文地址:https://www.cnblogs.com/YuanZiming/p/5720799.html