zoukankan      html  css  js  c++  java
  • P1182 数列分段`Section II` P1316 丢瓶盖 二分答案

    题目描述

    对于给定的一个长度为N的正整数数列A-iAi,现要将其分成M(M≤N)M(MN)段,并要求每段连续,且每段和的最大值最小。

    关于最大值最小:

    例如一数列4 2 4 5 142451要分成33段

    将其如下分段:

    [4 2][4 5][1][42][45][1]

    第一段和为66,第22段和为99,第33段和为11,和最大值为99。

    将其如下分段:

    [4][2 4][5 1][4][24][51]

    第一段和为44,第22段和为66,第33段和为66,和最大值为66。

    并且无论如何分段,最大值不会小于66。

    所以可以得到要将数列4 2 4 5 142451要分成33段,每段和的最大值最小为66。

    输入输出格式

    输入格式:

    11行包含两个正整数N,M。

    22行包含NN个空格隔开的非负整数A_iAi,含义如题目所述。

    输出格式:

    一个正整数,即每段和最大值最小为多少。

    输入输出样例

    输入样例#1: 复制
    5 3
    4 2 4 5 1
    输出样例#1: 复制
    6

    说明

    对于20\%20%的数据,有N≤10N10;

    对于40\%40%的数据,有N≤1000N1000;

    对于100\%100%的数据,有N≤100000,M≤N, A_iN100000,MN,Ai之和不超过10^9109。

    题目都很水

    规范二分写法!!!

    #include<bits/stdc++.h>
    using namespace std;
    //input by bxd
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define repp(i,a,b) for(int i=(a);i>=(b);i--)
    #define RI(n) scanf("%d",&(n))
    #define RII(n,m) scanf("%d%d",&n,&m)
    #define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
    #define RS(s) scanf("%s",s);
    #define LL long long
    #define REP(i,N)  for(int i=0;i<(N);i++)
    #define CLR(A,v)  memset(A,v,sizeof A)
    //////////////////////////////////
    #define inf 214748347
    #define N 100005
    int a[N];
    
    int main()
    {
        int n,k;
        RII(n,k);
        int R=0;
        int L=0;
        rep(i,1,n)
        {
            RI(a[i]);R+=a[i];
            L=max(L,a[i]);
        }
        while(L<R)
        {
            int mid=(L+R)>>1;
    
            int cnt=0;
            int temp=0;
            rep(i,1,n)
            {
                temp+=a[i];
                if(temp>mid)
                    cnt++,temp=a[i];
            }
            if(temp)cnt++;
    
            if(cnt>k)L=mid+1;
            else R=mid;//答案求的是最小值  所以当有=时右往左靠
        }
        cout<<L;
        return 0;
    }
    View Code

    题目描述

    陶陶是个贪玩的孩子,他在地上丢了A个瓶盖,为了简化问题,我们可以当作这A个瓶盖丢在一条直线上,现在他想从这些瓶盖里找出B个,使得距离最近的2个距离最大,他想知道,最大可以到多少呢?

    输入输出格式

    输入格式:

    第一行,两个整数,A,B。(B<=A<=100000)

    第二行,A个整数,分别为这A个瓶盖坐标。

    输出格式:

    仅一个整数,为所求答案。

    输入输出样例

    输入样例#1: 复制
    5 3
    1 2 3 4 5
    
    输出样例#1: 复制
    2


    二分答案 最好的方法!!!!!!!
    #include<bits/stdc++.h>
    using namespace std;
    //input by bxd
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define repp(i,a,b) for(int i=(a);i>=(b);i--)
    #define RI(n) scanf("%d",&(n))
    #define RII(n,m) scanf("%d%d",&n,&m)
    #define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
    #define RS(s) scanf("%s",s);
    #define ll long long
    #define REP(i,N)  for(int i=0;i<(N);i++)
    #define CLR(A,v)  memset(A,v,sizeof A)
    //////////////////////////////////
    #define inf 214748347
    #define N 100005
    ll a[N];
    int n,k;
    bool check(ll x)//x为最近距离
    {
        int cnt=1;
        int temp=1;
        rep(i,2,n)
        {
            if(a[i]-a[temp]>=x)
                cnt++,temp=i;
        }
        return cnt>=k;
    }
    int main()
    {
       RII(n,k);
       rep(i,1,n)
          cin>>a[i];
    
       sort(a+1,a+1+n);
       ll R=a[n]-a[1];
       ll L=0;
       ll ans=0;
       while(L<=R)
       {
           ll mid=(L+R)>>1;
           if(check(mid))L=mid+1,ans=max(ans,mid);
           else  R=mid-1;
       }
       cout<<L-1;
       return 0;
    }
    View Code

    其他写法:

    #include<bits/stdc++.h>
    using namespace std;
    //input by bxd
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define repp(i,a,b) for(int i=(a);i>=(b);i--)
    #define RI(n) scanf("%d",&(n))
    #define RII(n,m) scanf("%d%d",&n,&m)
    #define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
    #define RS(s) scanf("%s",s);
    #define ll long long
    #define REP(i,N)  for(int i=0;i<(N);i++)
    #define CLR(A,v)  memset(A,v,sizeof A)
    //////////////////////////////////
    #define inf 214748347
    #define N 100005
    ll a[N];
    int n,k;
    bool check(ll x)//x为最近距离
    {
        int cnt=1;
        int temp=1;
        rep(i,2,n)
        {
            if(a[i]-a[temp]>=x)
                cnt++,temp=i;
        }
        return cnt>=k;
    }
    int main()
    {
       RII(n,k);
       rep(i,1,n)
          cin>>a[i];
    
       sort(a+1,a+1+n);
       ll R=a[n]-a[1];
       ll L=0;
       ll ans=0;
       while(L<R)
       {
           ll mid=(L+R+1)>>1;
           if(check(mid))L=mid;
           else  R=mid-1;
       }
       cout<<L;
       return 0;
    }
    View Code
    #include<bits/stdc++.h>
    using namespace std;
    //input by bxd
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define repp(i,a,b) for(int i=(a);i>=(b);i--)
    #define RI(n) scanf("%d",&(n))
    #define RII(n,m) scanf("%d%d",&n,&m)
    #define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
    #define RS(s) scanf("%s",s);
    #define ll long long
    #define REP(i,N)  for(int i=0;i<(N);i++)
    #define CLR(A,v)  memset(A,v,sizeof A)
    //////////////////////////////////
    #define inf 214748347
    #define N 100005
    ll a[N];
    int n,k;
    bool check(ll x)//x为最近距离
    {
        int cnt=1;
        int temp=1;
        rep(i,2,n)
        {
            if(a[i]-a[temp]>=x)
                cnt++,temp=i;
        }
        return cnt>=k;
    }
    int main()
    {
       RII(n,k);
       rep(i,1,n)
          cin>>a[i];
    
       sort(a+1,a+1+n);
       ll R=a[n]-a[1];
       ll L=0;
       ll ans=0;
       while(L<=R)
       {
           ll mid=(L+R)>>1;
           if(check(mid))L=mid+1;
           else  R=mid-1;
       }
       cout<<L-1;
       return 0;
    }
    View Code
  • 相关阅读:
    appium-flutter-driver 测试flutter_boost项目_Java语言
    appium-flutter-driver 测试flutter项目
    Android Studio 制作出来的9图无法进行拖拉,导致无法制作出正确的9图
    Flutter 正确删除emoji表情/正确分割字符串
    如何清除git仓库的所有提交记录,成为一个新的干净仓库
    js中this的总结
    python判断时间是否在某个时间段里面的三种方式
    centos7使用rpm包安装mysql5.74
    django学习之 从服务端上传文档与下载文档接口
    python 之阿里云短信服务接入流程短信接口
  • 原文地址:https://www.cnblogs.com/bxd123/p/10691843.html
Copyright © 2011-2022 走看看