zoukankan      html  css  js  c++  java
  • noi寒假刷题之旅_ 1.11编程基础之二分查找(10题)

    »1.11编程基础之二分查找(10题)

    01:查找最接近的元素

    #include<iostream>
    #include<algorithm>
    #include<cmath> 
    #define MAX 100004
    using namespace std;
    int t[MAX];
    int main()
    {
    	int n;cin>>n;
    	for(int i=0;i<n;++i)cin>>t[i];
    	int m,a,low=0,high=n-1,f;cin>>m;
    	for(int i=0;i<m;++i)
    	{
    		cin>>a;
    		low=0,high=n-1,f=1;
    		if(a<=t[low]){		cout<<t[low]<<endl;continue; }
    		if(a>=t[high]){		cout<<t[high]<<endl;continue; }
    		while(low<=high) 
    		{
    			int mid=(low+high)/2;
    			if(t[mid]<a) low=mid+1;
    			else high=mid-1;
    		}	
    		f = (abs(t[low]-a) < abs(t[high]-a)) ? low : high;
    		cout<<t[f]<<endl;
    	}
    	return 0;
    } 

    02:二分法求函数的零点

    #include<iostream>
    #include<algorithm>
    #include<cmath> 
    #define MAX 100004
    using namespace std;
    double t[6][2]={{1,5},{-15,4},{85,3},{-225,2},{274,1},{-121,0}};
    double f(double x)
    {
    	return pow(x,5)-15.0*pow(x,4)+85.0*pow(x,3)-225.0*pow(x,2)+274.0*x-121.0;
    }
    int main()
    {
    	double low=1.5,high=2.4, mid;
    	while(fabs(low-high)>1e-15) 
    	{
    		mid=(low+high)/2.0;
    		double re=f(mid);
    		if(re>0) low=mid;
    		else high=mid;
    	}	
    	printf("%.6lf",mid);
    	return 0;
    } 
    

    03:矩形分割

    【降维,终于知错了if(Check(kk))与if(Check(kk)>0)是不一样的,一个是非0一个是大于0】

    #include<iostream>
    #include<algorithm>
    #include<cmath> 
    #define MAX 1000005
    using namespace std;
    int a[MAX];
    int r,n,k,L,T, W, H;
    long long Check(int k)
    {
    	long long c=0,b=0;
    	for(int i=0;i<k;++i) c+=a[i];
    	for(int i=k;i<r;++i) b+=a[i];
    	return c-b; 
    }
    int main()
    {
    	scanf("%d%d",&r,&n);
    	for(int i=0;i<n;++i)
    	{
    		scanf("%d%d%d%d",&L,&T,&W,&H);
    		for(int i=L;i<L+W;++i) a[i]+=H; 
    	}
    	int low=0,high=r;
    	while(low+3<high)
    	{
    		int kk=(low+high)/2;
    		if(Check(kk)>0) high=kk;
    		else low=kk;
    	}
    	long long su=0x3f3f3f3f;
    	for(int i=high;i>=low;--i)
    	{
    		long long m=Check(i);
    		if(m<su&&m>=0)
    		{
    			su=m;k=i;
    		}
    	}
    	while(a[k]==0&&k<r)k++;
    	printf("%d",k);
    	return 0;
    } 
    

    04:网线主管

    【可烦死这种求精度的了,long long的精度比int高,自己用整形取上整提精度】

    #include<iostream>
    #include<algorithm>
    #include<cmath> 
    #define MAX 1000005
    using namespace std;
    double x;
    long long a[MAX],t,sum,z,mid;
    int n,k;
    int main()
    {
    	scanf("%d%d",&n,&k);
    	for(int i=0;i<n;++i)
    	{
    		scanf("%lf",&x);
    		a[i]=int(x*100.00+0.5);//提炼一下精度 
    		z = z > a[i] ? z : a[i]; 
    		sum+=a[i]; 
    	}
    	int low = z/k;//最小长度
    	int high= sum/k;//最大长度 
    	while(low<high)
    	{
    		mid=(low+high+1)/2,t=0;
    		for(int i=0;i<n;++i) t+=int(a[i]/mid);
    		if(t>=k)low=mid;
    		else high=mid-1;
    	}
    	printf("%.2lf",low/100.00);
    }
    

    05:派

    #include<iostream>
    #include<algorithm>
    #include<cmath> 
    #define MAX 1000005
    using namespace std;
    double x;
    double a[MAX],sum,z,mid;
    int n,k,t;//保存每一个派的体积 
    double f(double r)
    {
    	return r*r*3.1415926535897932;
    }
    int main()
    {
    	scanf("%d%d",&n,&k);k++;
    	for(int i=0;i<n;++i)
    	{
    		scanf("%lf",&x);
    		a[i]=f(x);
    		z = z > a[i] ? z : a[i]; //找体积最大的 
    	}
    	double low = 0,high=z;
    	while(low<=high)
    	{
    		mid=(low+high)/2,t=0;
    		for(int i=0;i<n;++i) t+=int(a[i]/mid);
    		if(t>=k)low=mid+0.000001;
    		else high=mid-0.000001;
    	}
    	printf("%.3lf",mid);
    }
    

    06:月度开销

    #include<iostream>
    #include<algorithm>
    #include<cmath> 
    #define MAX 1000005
    using namespace std;
    int a[MAX],t,mid;
    int n,m,low = 0,high=0;
    int f(int mid)
    {
        int count=1,i,temp=0;
        for(i=0;i<n;i++)
        {
            if(temp+a[i]<=mid) temp+=a[i];
            else if(a[i]<=mid)
            {
                count++;
                temp=a[i];
                if(count>m) return -1;
            }
            else return -1;
        }
        if(count>m) return -1;
        else if(count<=m) return 1;
    }
    int main()
    {
    	scanf("%d%d",&n,&m);
    	for(int i=0;i<n;++i)
    	{
    		scanf("%d",&a[i]);
    		low = low > a[i] ? low : a[i];
    		high+=a[i];
    	}
    	while(low<high)
    	{
    		mid=(low+high)/2,t=f(mid);
    		if(t==-1)low=mid+1;
    		else high=mid;
    //		cout<<low<<"_"<<mid<<"_"<<high<<endl; 
    	}
    	printf("%d",low);
    }
    

    07:和为给定数

    #include<iostream>
    #include<algorithm>
    #include<cmath> 
    #define MAX 1000005
    using namespace std;
    int a[MAX],t,mid,flag=1;
    int n,m,low = 0,high=0;
    int main()
    {
    	scanf("%d",&n);
    	for(int i=0;i<n;++i)scanf("%d",&a[i]);
    	scanf("%d",&m);
    	sort(a,a+n);
    	for(int i=0;i<n;++i)//小值 
    	{
    		low=i+1,high=n-1;
    		while(low<=high)//大值 
    		{
    			mid=(low+high)>>1;	
    			if(a[mid]+a[i]<m){	low=mid+1;		} 
    			else if(a[mid]+a[i]>m) {	high=mid-1;		}
    			else { 	printf("%d %d",a[i],a[mid]);flag=0;goto stop;	}
    		}
    	}
    	stop:if(flag)
    	{
    		cout<<"No";
    	}return 0;
    }
    

    08:不重复地输出数

    【不知道二分在哪里】

    #include<iostream>
    #include<algorithm>
    #include<cmath> 
    #define MAX 1000005
    using namespace std;
    int a[MAX],t,mid,flag=1;
    int n,m,low = 0,high=0;
    int main()
    {
    	scanf("%d",&n);
    	for(int i=0;i<n;++i)scanf("%d",&a[i]);
    	sort(a,a+n);
    	for(int i=0;i<n;++i)//小值 
    	{
    		if(a[i]!=a[i+1]) cout<<a[i]<<" ";
    	}
    	return 0;
    }
    

    09:膨胀的木棍

    【数学公式能化简化简,把三角函数的都化到最简单,不然精度上不去】

    #include<iostream>
    #include<algorithm>
    #include<cmath> 
    #define MAX 1000005
    using namespace std;
    double L,n,C,low=0,high,mid;
    int main()
    {
    	scanf("%lf%lf%lf",&L,&n,&C);
    	if(L<1e-14)
    	{
    		printf("0.000");
    		return 0;	
    	} 
    	double LL=(1+n*C)*L;
    	high=asin(1.0);//90° 
    	while(high-low>1e-14)
    	{
    		mid = (low+high)/2;
    		if( LL * sin(mid)/mid <= L ) high=mid;
    		else low=mid;
    	}
    	printf("%.3lf",L/2*tan(mid/2));
    	return 0;
    }
    

    10:河中跳房子

    #include<iostream>
    #include<algorithm>
    #include<cmath> 
    #define MAX 50010
    using namespace std;
    int L,N,M,s[MAX];
    bool f(int mid)
    {
    	int bp=0,leaf=0;
    	for(int sp=1;sp<=N+1;++sp)
    	{
    		if(s[sp]-s[bp]>=mid){	leaf++;bp=sp;	}
    	}
    	if(leaf>N-M)return true;
    	else return false;
    }
    int main()
    {
    	scanf("%d%d%d",&L,&N,&M);
    	for(int i=1;i<=N;++i)scanf("%d",&s[i]);s[N+1]=L;
    	int low=1,heigh=L,ans=0;
    	while(low<=heigh)
    	{
    		int mid=(low+heigh)/2;
    		if(f(mid)) {	ans=mid;low=mid+1;	}
    		else {  heigh=mid-1;		}
    	}
    	printf("%d",ans);
    	return 0;
    }
    

      

  • 相关阅读:
    HDU6808 Go Running(未解决问题
    K
    E
    D
    B
    I
    HDU 2255 奔小康赚大钱 (KM算法模板)
    hdu 1150 Machine Schedule(二分图模板题)
    ACM-ICPC 2018 焦作赛区网络预赛G Give Candies(欧拉降幂)
    ACM-ICPC 2018 焦作赛区网络预赛 L:Poor God Water(杜教BM)
  • 原文地址:https://www.cnblogs.com/chrysanthemum/p/12248120.html
Copyright © 2011-2022 走看看