二分专题题解

Aggressive cows

http://poj.org/problem?id=2456

题目大意为给一条直线上的n个点,让你随意选取c个点,然后使得这c个点两两之间的最小距离最大,如何选取这c个点使这个最小距离最大,输出最大的最小距离max。

思路

先把坐标排序,之后界定二分的范围,二分的缩小范围的条件则为当两点距离大于所输入的点时,s++,返回s。如若s大于所处的点,说明值太小,将左界变为mid+1,反之将右界赋值为mid-1;当左界与右界之差小于1的时候跳出循环,输出。

 

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int mini(int x,int a[],int n)
{
	int p=a[0];
	int s=1;
	int i;
	for(i=1;i<n;i++)
	{
		if(a[i]-p>=x)
		{
			s++;
			p=a[i];
		}
	}
	
	return(s);
}
int comp(const void*a,const void*b)
{
return *(int*)a-*(int*)b;
}

int main()
{
	int n,c;
	int a[100100];
	int left,right;
	while(scanf("%d%d",&n,&c)!=EOF)
	{
		int i;
		for(i=0;i<n;i++)
		scanf("%d",&a[i]);
		qsort(a,n,sizeof(int),comp);
		left=0;
		right=a[n-1]-a[0];
		while(right>=left)
		{
			int mid=(left+right)/2;
			if(mini(mid,a,n)>=c)
			left=mid+1;
			else
			right=mid-1;
		}
		
		printf("%d\n",left-1);
	}
	
	return 0;
}

 

 

River Hopscotch

http://poj.org/problem?id=3258

 题意是给了n个石头,给了它们到起点的距离,还有一个终点。问要去掉这n个石头中的m个,使得其间距的最小值最大。

思路

这题放在这里是因为和第一题类似。代码只要稍作修改就可以ac。与第一题的区别在于,放多少头牛变为了减去后石头所剩,但因为收尾不能动,所以需要有n-m+2个。其他过程相似,在做的时候有个小疑问,就是如何确保首尾一定放着牛,但后来发现是杞人忧天。

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int mini(int x,int a[],int n)
{
	int p=0;
	int s=0;
	int i;
	for(i=0;i<=n;i++)
	{
		if(a[i]-p>=x)
		{
			s++;
			p=a[i];
		}
	//	if(s>n-m)
	//	return 1;
	}
	
	return s;
}
int comp(const void*a,const void*b)
{
return *(int*)a-*(int*)b;
}

int main()
{
	int L,N,M;
	int a[50100];
	int left,right;
	while(scanf("%d%d%d",&L,&N,&M)!=EOF)
	{
		int i;
		for(i=0;i<N;i++)
		scanf("%d",&a[i]);
		
		a[N]=L;
		qsort(a,N+1,sizeof(int),comp);
		left=0;
		right=L;
		while(right>=left)
		{
			int mid=(left+right)/2;
			if(mini(mid,a,N)>=N-M+1)
			left=mid+1;
			else
			right=mid-1;
		}
		
		printf("%d\n",left-1);
	}
	
	return 0;
}

Drying

http://poj.org/problem?id=3104

题意:有一些衣服,每件衣服有一定水量,有一个烘干机,每次可以烘一件衣服,每分钟可以烘掉k。每件衣服没分钟可以自动蒸发掉一滴水,用烘干机烘衣服时不蒸发。问最少需要多少时间能烘干所有的衣服。

思路

这里进行的二分是对时间的二分,寻找一个最小时间。先设定边界,再取中间值。当中间值的时间大于烘干所用的时间时,说明时间短,对left边界取mid+1,相反,则说明时间还有缩减的可能,将right取mid-1,当left>right时跳出。

#include<stdio.h>
int judge(long long mid,long long a[],long long k,long long n)
{
	long long time=0;
	long long i;
	for(i=0;i<n;i++)
	{
		if(a[i]<=mid)
		continue;
		else
		{
			time+=(a[i]-mid+k-2)/(k-1);//(k-2)/(k-1) 为了获得类似0.999 
			if(time>mid)
			return 0;
	    }
	}
	return 1;
}
int main()
{
	int N;
	long long k;
	while(scanf("%d",&N)!=EOF)
	{
		long long a[100010];
	    long long k;
	    long i;
	    long long max=0;
	    long long l,r;
	    for(i=0;i<N;i++)
	    {
	    	scanf("%lld",&a[i]);
	    	if(a[i]>max)
	    	{
	    		max=a[i];
	    	}
	    }
	    scanf("%lld",&k);
	    l=0;
	    r=max;
	    if(k==1)
	    {
	    	printf("%d\n",max);
	    	break;
	    }
	    else
	    {
	    	long long mid;
	    	while(r-l>1)
	    	{
	    		mid=(r+l)/2;
	    		if(judge(mid,a,k,N))
	    		{
	    			r=mid;
	    		}
	    		else l=mid;
	    		//printf("%d\n",r);
	    	}
	    }
	    printf("%d\n",r);
	}
	return 0;
}

 

 

Expanding Rods

题意 有一根绳子的长度为l,在有温度的情况下会变形为一个圆弧,长度为 l1 = (n*c+1)*l;求图中的h;并说明增加的长度不超过原长度的一半。

 

 思路

数学问题,找到公式后用二分法确定精度。

#include<stdio.h>
#include<math.h>
const double esp=1e-8;
int main()
{
    double l,n,c,s;
    double r;
    int T;
    int i;
    while(scanf("%d",&T)!=EOF)
	{
	for(i=1;i<=T;i++)
	{
	 
    scanf("%lf%lf%lf",&l,&n,&c);
    
        if(l<0&&n<0&&c<0)
        {
            break;
        }
        if(l==0||n==0||c==0)
        {
        	printf("Case %d: 0\n",i);
        	continue;
        }
        double low=0.0;
        double high=0.5*l;
        double mid;
        s=(1+n*c)*l;
        while(high-low>esp)
        {
            mid=(low+high)/2;
            r=(4*mid*mid+l*l)/(8*mid);
            if( 2*r*asin(l/(2*r)) < s )
                low=mid;
            else
                high=mid;
        }
        printf("Case %d: %.7lf\n",i,mid);
    
    }
    }
    return 0;
}
    

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值