POJ1905解题报告

题目链接

 

题目的那点在于如何求解角度,这里采用的方法是二分求解:

一般地,对于函数f(x),如果存在实数c,当x=c时f(c)=0,那么把x=c叫做函数f(x)的零点。 
解方程即要求f(x)的所有零点。
先找到a、b,使f(a),f(b)异号,说明在区间(a,b)内一定有零点,然后求f[(a+b)/2],
现在假设f(a)<0,f(b)>0,a<b
①如果f[(a+b)/2]=0,该点就是零点,
如果f[(a+b)/2]<0,则在区间((a+b)/2,b)内有零点,(a+b)/2=>a,从①开始继续使用
中点函数值判断。
如果f[(a+b)/2]>0,则在区间(a,(a+b)/2)内有零点,(a+b)/2=>b,从①开始继续使用
中点函数值判断。
这样就可以不断接近零点。
通过每次把f(x)的零点所在小区间收缩一半的方法,使区间的两个端点逐步迫近函数的零点,以求得零点的近似值,这种方法叫做二分法。
(以上摘自百度)

因此,可以用二分迭代的方式求解该题的角度。
当两点之间的距离小于一个阈值时,停止迭代计算,输出结果即可。
代码如下:
#include <iostream> #include <cstdio> #include <cmath> using namespace std; const double MyError = 10e-12; const double PI = atan(1.0)*4; double alpha; double f(const double &x) { return alpha*sin(x)-x; } double GetSita(double b,double e) { //recursion // double now = e-b; // if(now< MyError && now >0) // return e; // else now = (b+e)/2; // if(f(now)>0.0) // return GetSita(now,e); // else return GetSita(b,now); double now = e-b; while (now >MyError) { now = (b+e)/2; if( f(now) > 0.0) b = now; else e = now; now = e-b; } return e; } int main() { double n,L,c; while(cin>>L>>n>>c) { if(n == -1 && L == -1 && c == -1) break; if(n<MyError || c< MyError) { cout<<"0.000"<<endl; continue; } alpha =1.0+ n*c; double sita = GetSita(double(1e-5),10.0); printf("%.3f/n",L/2/tan( (PI-sita)/2 )); } return 0; }

这里还要说的一点就是不能走意识流的路线,看着题目中的n和L是整数就以为它们真的是整数?F**K,那是POJ逗你玩。。。白WA了两次。。。

你可能感兴趣的:(POJ1905解题报告)