小白算法练习 二分搜素练习 Drying POJ 3104 lanqiao 二分

Drying
Time Limit: 2000MS Memory Limit: 65536K
Total Submissions: 18239 Accepted: 4599

Description

It is very hard to wash and especially to dry clothes in winter. But Jane is a very smart girl. She is not afraid of this boring process. Jane has decided to use a radiator to make drying faster. But the radiator is small, so it can hold only one thing at a time.

Jane wants to perform drying in the minimal possible time. She asked you to write a program that will calculate the minimal time for a given set of clothes.

There are n clothes Jane has just washed. Each of them took ai water during washing. Every minute the amount of water contained in each thing decreases by one (of course, only if the thing is not completely dry yet). When amount of water contained becomes zero the cloth becomes dry and is ready to be packed.

Every minute Jane can select one thing to dry on the radiator. The radiator is very hot, so the amount of water in this thing decreases by k this minute (but not less than zero — if the thing contains less than kwater, the resulting amount of water will be zero).

The task is to minimize the total time of drying by means of using the radiator effectively. The drying process ends when all the clothes are dry.

Input

The first line contains a single integer n (1 ≤ n ≤ 100 000). The second line contains ai separated by spaces (1 ≤ ai ≤ 109). The third line contains k (1 ≤ k ≤ 109).

Output

Output a single integer — the minimal possible number of minutes required to dry all clothes.

Sample Input

sample input #1
3
2 3 9
5

sample input #2
3
2 3 6
5

Sample Output

sample output #1
3

sample output #2
2

代码

#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int Max = 100008;
typedef long long ll;
ll dry[Max];
ll dry_c[Max];
int n; //有多少个数 
int k; // 一次能晾干多少水 
bool solve(ll u){
	for(int i=0;i<n;i++)
	{
		dry_c[i]-=u;
	}	
	if(k==1){
		for(int i=0;i<n;i++)
		{
			if(dry_c[i]>0)
			{
				return false;
			}
		}
		return true;
	}
	int sum=0;
	for(int i=0;i<n;i++)
	{
		if(dry_c[i]>0)
		{
			if(dry_c[i]%(k-1))
			{
				sum+=dry_c[i]/(k-1)+1;
			}
			else
			{
				sum+=dry_c[i]/(k-1);	
			}		
		}
		if(sum>u) return false;
	} 
	return true;
}
int main(){
//	while(scanf("%d",&n)!=EOF){
	scanf("%d",&n);
		ll low=1;
		ll high=-1; 
		ll mid;
		for(int i=0;i<n;i++)
		{
			scanf("%lld", &dry[i]);
			high=max(high,dry[i]);
		}
		scanf("%d",&k);//代表 能蒸发水量 k 滴水
		while(low<high-1)
		{
			memcpy(dry_c,dry,sizeof(dry));
			mid=(low+high)/2;
			if(solve(mid)==false)
			{
				low=mid;
			}
			else
			{
				high=mid;
			}
		}
		cout<<high<<endl;
	return 0;
} 

PS:我超时了n次,结果在discuss中发现不能用cin,改成了scanf,然后又把k==1单独考虑。。

Pie
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 18822 Accepted: 6202 Special Judge

Description

My birthday is coming up and traditionally I'm serving pie. Not just one pie, no, I have a number N of them, of various tastes and of various sizes. F of my friends are coming to my party and each of them gets a piece of pie. This should be one piece of one pie, not several small pieces since that looks messy. This piece can be one whole pie though. 

My friends are very annoying and if one of them gets a bigger piece than the others, they start complaining. Therefore all of them should get equally sized (but not necessarily equally shaped) pieces, even if this leads to some pie getting spoiled (which is better than spoiling the party). Of course, I want a piece of pie for myself too, and that piece should also be of the same size. 

What is the largest possible piece size all of us can get? All the pies are cylindrical in shape and they all have the same height 1, but the radii of the pies can be different.

Input

One line with a positive integer: the number of test cases. Then for each test case:
  • One line with two integers N and F with 1 ≤ N, F ≤ 10 000: the number of pies and the number of friends.
  • One line with N integers ri with 1 ≤ ri ≤ 10 000: the radii of the pies.

Output

For each test case, output one line with the largest possible volume V such that me and my friends can all get a pie piece of size V. The answer should be given as a floating point number with an absolute error of at most 10 −3.

Sample Input

3
3 3
4 3 3
1 24
5
10 5
1 4 2 3 4 5 6 5 4 2

Sample Output

25.1327
3.1416
50.2655
代码
#include<iostream>
#include<iomanip>  
#include<stdio.h>
#include<cmath>
#define pi 4*atan(1.0)
using namespace std;
int N,F;//pie 数量 friend 数量
int R[100010];
double V[100010];
int solve(double u){
	int res(0);
	for(int i=0;i<N;i++)
	{
		res+=(int)( V[i]/u );
	}
	if(res>=F)
	{
		return 1;
	}
	else
	{
		return 0;
	}
}
int main(){
	int T;
	cin>>T;
	while(T--)
	{
		//input & init
		cin>>N>>F;
		F=F+1;
		double Max=0.0;
		for(int i=0;i<N;i++)
		{
			cin>>R[i]; //半径	
			V[i]=R[i]*R[i];
			if(Max<V[i])
			{
				Max=V[i];	
			} 
		} 
		double low=0.0;
		double high=Max;
		while(high-low>1e-7)
		{
			double mid=(low+high)/2;
			if(solve(mid)==1)
			{
				low=mid;
				high=high;
			}
			else
			{
				high=mid;
				low=low;
			}
		}
//		cout<<fixed<<setprecision(4)<<low*pi<<endl; 
		printf("%.4lf\n",low*pi);
	}
	return 0;
} 


标题: 分巧克力
儿童节那天有K位小朋友到小明家做客。小明拿出了珍藏的巧克力招待小朋友们。
小明一共有N块巧克力,其中第i块是Hi x Wi的方格组成的长方形。
为了公平起见,小明需要从这 N 块巧克力中切出K块巧克力分给小朋友们。切出的巧克力需要满足:
     1. 形状是正方形,边长是整数  
     2. 大小相同  
例如一块6x5的巧克力可以切出6块2x2的巧克力或者2块3x3的巧克力。
当然小朋友们都希望得到的巧克力尽可能大,你能帮小Hi计算出最大的边长是多少么?
输入
第一行包含两个整数N和K。(1 <= N, K <= 100000)  
以下N行每行包含两个整数Hi和Wi。(1 <= Hi, Wi <= 100000) 
输入保证每位小朋友至少能获得一块1x1的巧克力。   
输出
输出切出的正方形巧克力最大可能的边长。
样例输入:
2 10  
6 5  
5 6  
样例输出:
2
资源约定:
峰值内存消耗(含虚拟机) < 256M
CPU消耗  < 1000ms
请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。
注意:
main函数需要返回0;
只使用ANSI C/ANSI C++ 标准;
不要调用依赖于编译环境或操作系统的特殊函数。
所有依赖的函数必须明确地在源文件中 #include <xxx>
不能通过工程设置而省略常用头文件。

提交程序时,注意选择所期望的语言类型和编译器类型。

#include<iostream>
using namespace std;


int r[100008];
int c[100008];
int C,F;


int solve(int u){
	int res(0);
	for(int i=0;i<C;i++)
	{
		int x=r[i]/u;
		int y=c[i]/u;
		res+=x*y;
	}
	if(res>F)
	{
		return 0;//小了 
	}
	return 1;//大了 	
}
int main(){
	
	cin>>C>>F;
	
	for(int i=0;i<C;i++)
	{
		cin>>r[i]>>c[i];
	}
	int res(0);


	int low=1;
	int high=100008;
	
	while(low<high-1)
	{
		int mid=(low+high)>>1;
		if(solve(mid)==0)
		{
			low=mid; 
		}
		else
		{
			high=mid;
		}
	}
	
	cout<<low<<endl;
} 


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值