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
原文地址:https://www.cnblogs.com/bxd123/p/10691843.html