acm常用技巧一 二分 poj 1064 poj 2456

来源:互联网 发布:混沌与秩序数据 编辑:程序博客网 时间:2024/06/05 08:15

一.二分搜索

void Fun(){//lower_bound实现,不存在的情况下输出n    int lb=-1,ub=n;    while(ub-lb>1){//重复循环,直到解的范围<=1        int mid=(lb+ub)/2;        if(a[mid]>=k)            ub=mid;//如果mid满足条件解的存在范围变成(lb,mid]        else            lb=mid;//如果不满足条件(mid,ub]    }    //lb+1=ub    printf("%d\n",ub);}


二.POJ 1064

给你n个木棍,你要把他们截成k个相同的小木棍,求小木棍的最大长度

#include <functional>#include <algorithm>#include <iostream>#include <fstream>#include <sstream>#include <iomanip>#include <numeric>#include <cstring>#include <climits>#include <cassert>#include <cstdio>#include <string>#include <vector>#include <bitset>#include <queue>#include <stack>#include <cmath>#include <ctime>#include <list>#include <set>#include <map>using namespace std;typedef long long LL;const int MOD =1e9 + 7;const int INF = 0x3f3f3f3f;const int MXN=1e6;int N,M;void Rush(){    int T;    scanf("%d",&T);    for(int kas=1;kas<=T;++kas)    {        printf("Case %d: ",kas);    }}int K;double L[MXN];bool C(double x){    int num=0;    for(int i=0;i<N;++i)        num+=(int)(L[i]/x);    return num>=K;}void Fun(){    double lb=0,ub=1e10;    for(int i=0;i<100;++i){        double mid=(lb+ub)/2;        if(C(mid)) lb=mid;        else ub=mid;    }    printf("%.2lf\n",floor(ub*100)/100);}int main() {    while(~scanf("%d%d",&N,&K))     {        for(int i=0;i<N;++i)            scanf("%lf",&L[i]);        Fun();    }    return 0;}

三.POJ 2456

题意:在一位坐标上给N个点,将C头牛放在N个点中的C个点上使C头牛之间的最小距离最大

解法:C(d):=可以使最近的两头牛的距离不小于d,求满足C(d)的最大的d

int N,M;int x[MXN];bool C(int d){    int last=0;    for(int i=1;i<M;++i){        int crt=last+1;        while(crt<N&&x[crt]-x[last]<d){            crt++;        }        if(crt==N) return 0;        last=crt;    }    return 1;}void Fun(){    sort(x,x+N);    int lb=0,ub=INF;    while(ub-lb>1){        int mid=(lb+ub)/2;        if(C(mid)) lb=mid;        else ub=mid;    }    printf("%d\n",lb);}

四.最大化平均值


int n,k;int w[MXN],v[MXN];double y[MXN];bool C(double x){    for(int i=0;i<n;++i){        y[i]=v[i]-x*w[i];    }    sort(y,y+n);    double sum=0;    for(int i=0;i<k;++i){        sum+=y[n-i-1];    }    return sum>=0;}void Fun(){    double lb=0,ub=INF;    for(int i=0;i<100;++i){        double mid=(lb+ub)/2;        if(C(mid)) lb=mid;        else ub=mid;    }    printf("%.2f\n",ub);}


原创粉丝点击