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
  • 相关阅读:
    字符串 CSV解析 表格 逗号分隔值 通讯录 电话簿 MD
    Context Application 使用总结 MD
    RxJava RxPermissions 动态权限 简介 原理 案例 MD
    Luban 鲁班 图片压缩 MD
    FileProvider N 7.0 升级 安装APK 选择文件 拍照 临时权限 MD
    组件化 得到 DDComponent JIMU 模块 插件 MD
    gradlew 命令行 build 调试 构建错误 Manifest merger failed MD
    protobuf Protocol Buffers 简介 案例 MD
    ORM数据库框架 SQLite 常用数据库框架比较 MD
    [工具配置]requirejs 多页面,多入口js文件打包总结
  • 原文地址:https://www.cnblogs.com/bxd123/p/10691843.html
Copyright © 2011-2022 走看看