【BZOJ4590】自動刷題機
阿新 • • 發佈:2018-08-20
lin long long 自動 etc getchar 沒有 如果 urn type
【思路分析】
比賽的時候想到了用二分+貪心,二分的部分與貪心的部分也寫對了,但是由於數據範圍未看沒有開long long,且二分左端點賦值過小導致WA掉
正解:二分+貪心
二分代碼的長度,貪心判斷能否達到,算法上沒什麽好說的,主要是細節處理上
關於細節處理:
- 開long long
- 右端點數據可以開的盡量大一點
- 輸出-1的點要特別小心
代碼:
#include<cstdio> #include<cmath> #include<cctype> #include<iostream> #include<cstring> #include<algorithm> #include<vector> #include<map> #include<set> using namespace std; inline long long read() { char chr=getchar(); long long f=1,ans=0; while(!isdigit(chr)) {if(chr=='-') f=-1;chr=getchar();} while(isdigit(chr)) {ans=(ans<<1)+(ans<<3)+chr-'0';chr=getchar();} return ans*f; } long long n,m,a[100005],l=1,r,mid,ans1=-1,ans2=-1; inline long long check(long long x){//貪心判斷解是否可行 long long s=0,num=0; for(int i=1;i<=n;i++){ s+=a[i]; if(s<0) s=0; if(s>=x) s=0,num++; } return num; } int main(){ n=read(),m=read(); for(int i=1;i<=n;i++) a[i]=read(); r=1e18;//開得盡量大一點 while(l<=r){ mid=l+r>>1; if(check(mid)<=m) ans1=mid,r=mid-1; else l=mid+1; }//取最小值 l=1,r=1e18; while(l<=r){ mid=l+r>>1; if(check(mid)<m) ans2=mid,r=mid-1; else l=mid+1; }//取最大值 ans2--; if(ans1>ans2||ans1==-1||ans2==-1) {//如果ans1沒有更新過 或者 ans2沒有更新過 或者 //小的答案大於大的答案 printf("-1"); return 0; } printf("%lld %lld",ans1,ans2); return 0; }
【BZOJ4590】自動刷題機