【luoguP4343】自動刷題機
阿新 • • 發佈:2020-09-19
題目
題目背景
曾經發明瞭訊號增幅儀的發明家 SHTSC 又公開了他的新發明:自動刷題機——一種可以自動 AC 題目的神祕裝置。
題目描述
自動刷題機刷題的方式非常簡單:首先會瞬間得出題目的正確做法,然後開始寫程式。每秒,自動刷題機的程式碼生成模組會有兩種可能的結果:
1.寫了 x 行程式碼
2.心情不好,刪掉了之前寫的 y 行程式碼。(如果 y 大於當前程式碼長度則相當於全部刪除。)
對於一個 OJ,存在某個固定的正整數長度 n,一旦自動刷題機在某秒結束時積累了大於等於 n 行的程式碼,它就會自動提交併 AC 此題,然後新建一個檔案(即棄置之前的所有程式碼)並開始寫下一題。SHTSC 在某個 OJ 上跑了一天的自動刷題機,得到了很多條關於寫程式碼的日誌資訊。他突然發現自己沒有記錄這個 OJ 的 n 究竟是多少。所幸他通過自己在 OJ 上的 Rank 知道了自動刷題機一共切了 k 道題,希望你計算 n 可能的最小值和最大值。
輸入格式
第一行兩個整數 l,kl , kl,k,表示刷題機的日誌一共有 l 行,一共了切了 k 題。
接下來 l 行,每行一個整數 xi,依次表示每條日誌。若 xi≥0,則表示寫了 xi行程式碼,若 xi<0,則表示刪除了 -xi行程式碼。
輸出格式
輸出一行兩個整數,分別表示 n 可能的最小值和最大值。
如果這樣的 n 不存在,請輸出一行一個整數 −1。
連結:
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; }