Necklace

Necklace
Necklace鲁东OJ链接

题目来源:UVA 11001
The people of a certain tribe produce circular ceramic discs with equal diameter by some rare clay. A necklace is formed by connecting one or more discs. The figure below shows a necklace made with 4 discs. Its length is 4 times the diameter of each disc.

在这里插入图片描述
The thickness of each disc is fixed. The diameter D and the volume of clay used V has the following relationship:

在这里插入图片描述
where V0 is the volume consumed in the baking process, in the same unit of V . When V≤V0, no ceramic discs can be made. As an example, let Vtotal=10, V0=1. If we use it to make 1 disc, V=Vtotal=10, D=0.9. If we divide the clay into 2 parts, the volume of each part V=Vtotal/2=5, and diameter of each disc formed is D’=0.35−1−−−−√=0.6, thus the length of necklace formed this way is 1.2.

As per the above example, it is obvious that the lengths of necklaces differ as the number of discs made changes. Please write a program that computes the number of discs one should make so that the necklace formed is the longest.
INPUT
Each line of input contains two numbers, Vtotal (0 OUTPUT
Each line of output should give the number of discs one should make so that the necklace formed is the longest. If this number is not unique, or no necklaces can be formed at all, output ‘0’ instead.
样例输入
10 1
10 2
0 0
样例输出
5
0
题目大意分析
题目大意的解释:Vt是圆盘的体积,V0是制作圆盘时的损耗,设n为将总体体积为n份制作圆盘,使得圆盘的直径和达到最大!本题想让我们输出的是使得直径和最大的n的值。当vt=10,v0=1时,我们先来一个简单的考虑
如果总共只有一个圆盘,D=0.3 * sqrt(10-1);所以D=0.9,又因为一共只有一个圆盘,所以直径和是 1* 0.9=0.9。如果分成两份 则我们的总体积Vt要分成两份来求,这里值得注意的是,不管怎么份,单独做一份圆盘的体积损耗是不变的(从题干中的例题推理得到)!所以分成两份时,D=0.3 * sqrt(5-1)=0.6;又因为一共有两个圆盘,所以直径和=2*0.6=1.2;

题目做法分析
不难看出,直径和关于盘子数量的函数关系是:
L=0.3 * sqrt(vt/n-v0)*n; 我们将其中的常数和根号忽略掉之后,会得到一个式子: -n^2 * v0+n * vt ;显然这是一个一元二次方程组,利用初中的知识点可知,这是一个开口向下的函数,有最大值,最大值在 n=b/(-2a)取到,所以在这个式子中当n = vt/(2 * v0)时,可以得到直径和的最大值!
另外的注意事项
题目要求如果结果不唯一或者不能构成项链时直接输出0
:因为有的时候用上述 n=vt/(2 * v0)来计算时,可能不是整数,如果 n的小数部分是0.5,所以他就有左右各一个跟他最接近的整数,所以就构成了多解的情况,如果算出n的小数部分不是 0.5,将n四舍五入成整数解然后输出即可!

#include
using namespace std;
int main()
{
    double a,b;
	while(cin>>a>>b)
	{
		if(a==0&&b==0)
		break;//结束的条件! 
		else
		{//正常输入的情况! 
		if(a<=b)
		{
			printf("0\n");
		}
		else
		{ 
		   double h=a/(2*b);
		   if(h-(int)h!=0.5)
		   { 
			double s=h-(int)h;
			if(s>0.5)
			h=h-s+1;
			else if(s<0.5)
			h=h-s; //四舍五入! 
		   	printf("%d\n",(int)h); 
		   } 
			else//如果这个h值有0.5,因为是二次函数,所以可能有多个解! 
			printf("0\n");//说明的到的解不是整数,即可能有多个解! 
		}}
	 } 
      return 0;
} 

这个题总体来说还是比较水的,就当是我第一次打博客的练手题了。
题目解法有很多的赘述,是希望能讲的更加透彻
因为这个代码还没有验证过是不是正确的,所以如果代码有错误之处,或者哪里的解释和细节有疏漏,希望大家即使指正!我们一起共同进步。

做学问,一定要脚踏实地,慢慢的,慢慢的,我们就会翻过那座最高的山峰!

》》》》》》》》》》》》》》》》》》

你可能感兴趣的:(日常补题,UVA,c++)