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); }
给你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; }
题意:在一位坐标上给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); }