zoukankan      html  css  js  c++  java
  • 【BZOJ4590】自动刷题机

    【思路分析】

    比赛的时候想到了用二分+贪心,二分的部分与贪心的部分也写对了,但是由于数据范围未看没有开long long,且二分左端点赋值过小导致WA掉

    正解:二分+贪心

    二分代码的长度,贪心判断能否达到,算法上没什么好说的,主要是细节处理上

    关于细节处理:

    1. 开long long
    2. 右端点数据可以开的尽量大一点
    3. 输出-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;
    }
    
  • 相关阅读:
    变量的作用域
    内联函数inline
    数组、函数和指针
    关于android:configChanges的属性的简介
    Android 更新UI的两种方法
    android开发两种退出程序方式
    google内购In-App Billing
    谷歌登陆sdk对接
    openssl测试版本小工具
    关于facebook登陆不安装openssl的情况下怎么获得Facebook Key Hash的简单方法
  • 原文地址:https://www.cnblogs.com/zhenglw/p/9507863.html
Copyright © 2011-2022 走看看