二分答案模板

 

 

  •  ForwardIter lower_bound(ForwardIter first, ForwardIter last,const _Tp& val)算法返回一个非递减序列[first, last)中的第一个大于等于值val的位置。
  •      ForwardIter upper_bound(ForwardIter first, ForwardIter last, const _Tp& val)算法返回一个非递减序列[first, last)中第一个大于val的位置。
#include <iostream>  
#include <algorithm>//必须包含的头文件  
using namespace std;  
int main(){  
 int point[10] = {1,3,7,7,9};  
 int tmp = upper_bound(point, point + 5, 7) - point;//按从小到大,7最多能插入数组point的哪个位置  
 printf("%d\n",tmp);  
 tmp = lower_bound(point, point + 5, 7) - point;按从小到大,7最少能插入数组point的哪个位置  
 printf("%d\n",tmp);  
 return 0;  
}  

 

#include<bits/stdc++.h>  
using namespace std;  
typedef long long LL;  
const LL INF = 1e18+1000;  
const int MAXN = 1e6;  
LL a[MAXN];  
int cnt;  
void Init()  
{  
    cnt = 0;  
    for(LL i=1; i<INF; i*=2)  
        for(LL j=1; j*i<INF; j*=3)  
            for(LL k=1; i*j*k<INF; k*=5)  
                    a[cnt++] = i*j*k;  
}  
int main()  
{  
    Init();  
    sort(a,a+cnt);  
    int t;  
    cin>>t;  
    while(t--)  
    {  
        LL n;  
        scanf("%lld",&n);  
        printf("%lld\n",a[lower_bound(a+1,a+cnt+1,n)-a]);  
    }  
    return 0;  
}  
  • 例子   

POJ 3104  Drying  烘干衣服

题目来源:  http://poj.org/problem?id=3104  

#include<cmath>  
#include<iostream>  
using namespace std;  
  
int n;    //衣服件数   
int water[100010];    //水分   
int k;                //烘干机一次烘掉的水分   
  
int t=-1;    //最终答案:所有衣服干完的最少时间  
int maxT=-1;    //所有衣服干完最长用时   
  
//用时不超过mid (<=mid)能否烘干衣服, T=O(n)  
bool check(int mid){   
    /* 
      若某件衣服 i水分water[i]<mid,可以自然风干;否则需要烘。 
      假设这件衣服自然风干用时 t1, 烘烤用时 t2. 
          (1) t1+t2 = mid 
          (2) t1+k*t2 >= water[i] 
      ∴ t2 >= (water[i]-mid)/(k-1)  
      只需要判断使用烘干机的时间和是否 <= mid 即可  
    */   
    double radTime=0;  //使用烘干机的总时间   
      
    for(int i=0;i<n;i++){  
        if(water[i]>mid){  
            radTime += ceil( (double)(water[i]-mid)/(double)(k-1) );  //衣服 a[i]需要烘的次数   
        }   //???1. ceil()函数   
    }   
    if(radTime<=mid)  
        return true;  
    else  
        return false;  
}  
  
//所有衣服干完最少时间:[0,maxT], 二分答案 , T=O(log(maxT))O(n)  
void solve(){  
     int l=0;  
     int r=maxT;  
     int mid=(l+r)>>1;  //mid是在“二分答案 ”过程中每次观察的答案   
       
     //???2. 在二分查找中总结这种变形的二分查找: false, false, false, ..., false, true, true, ..., true  
     //      找第一个出现的 true 的位置   
     while(l<=r){  
         //每次进入循环,总能保证最终答案 t∈[l,r]   
           
         if(check(mid)==true){  
             if(check(mid-1)==false){//再少用1个单位的时间都不能烘干   
                 t=mid;            //最终答案:最少用时mid   
                 return;  
             }  
             r=mid-1;  
         }else{  
             l=mid+1;  
         }  
         mid=(l+r)>>1;  
     }  
}  
  
int main(void){  
    scanf("%d",&n); //???3. 看scanf()   
      
    //while(n>0){  
        //输入   
        int res=0;  
        for(int i=0;i<n;i++){  
            scanf("%d", &water[i]);  
            maxT=maxT>water[i]?maxT:water[i];  
        }  
        scanf("%d",&k);  
          
        //计算  & 输出   
        solve();  
        printf("%d\n",t);  
           
        //scanf("%d",&n);  
    //}  
    system("pause");  
    return 0;  
}  

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值