POJ1905 Expanding Rods 二分

Problem Address:http://poj.org/problem?id=1905


【前言】


练手二分,注定悲剧的一道题。

交上去WA。

担心是精度问题,改之,再WA。

再改,TLE。

看discuss。

一大片唏嘘声。

无奈,各种TLE和WA。

一牛说要看用什么方法二分。

然后改之。

之后又是各种WA和TLE。

后来看到神贴,说原来三个数都是浮点数= =

改之,再WA。

无奈,再加上某帖的判断其中是否有零。

终于AC!

然后找到第一份代码,加上浮点数和判断,果断AC= =

最后拿到8个WA和5个TLE,以及最后的2个AC。


【思路】


第一种:对圆心角进行二分,下限0,上限为π。

第二种:对高度进行二分,下限为0,上限为rod的初始长度的二分之一。

然后是各种几何运算,判断与目标长度的关系。

精度为  1e-6  即可过。

话说还有牛顿迭代法。没试。


【代码】


第一种:对圆心进行二分。

#include 
#include 
using namespace std;

const double pi = acos(-1.0);//π的高精度,话说某道题必须是这个值才能通过= =

int main()
{
	double len, n, c, length;
	double low, mid, high;
	double temp;
	while(scanf("%lf %lf %lf", &len, &n, &c)!=EOF)
	{
		if (len==-1 && n==-1 && c==-1) break;
		if (len==0 || n==0 || c==0)
		{
			printf("0.000\n");
			continue;
		}
		length = (1.0+n*c)*(double)len;
		low = 0;
		high = pi;
		len *= 0.5;
		while(fabs(low-high)>1e-12)//估计1e-6就能通过,后来没试
		{
			mid = (low+high)/2;
			temp = mid*len/sin(0.5*mid);
			if (temp<=length)
				low = mid;
			else
				high = mid;
		}
		printf("%.3lf\n", len*tan(mid*0.25));
	}
	return 0;
}



第二种:对高度进行二分

#include 
#include 
using namespace std;
int main()
{
	double len, n, c, length, r;
	double low, mid, high;
	double temp;
	while(scanf("%lf %lf %lf", &len, &n, &c)!=EOF)
	{
		if (len==-1 && n==-1) break;
		if (len==0 || n==0 || c==0)
		{
			printf("0.000\n");
			continue;
		}
		length = (1.0+n*c)*(double)len;
		low = 0;
		high = len;
		while(low


【P.S】


发现做完这道题后就可以去休息了……



你可能感兴趣的:(数学)