zoukankan      html  css  js  c++  java
  • UVa 11809 Floating-Point Numbers

    题目链接

    只是用来恢复状态,才做的水题,所以没什么好说的。

    观察题目,可以得到

    [left( 1 - dfrac{1}{2^{M + 1}} ight) imes 2^{2^E - 1} = A imes 10^B ]

    但是等式两边的值太大了,不好求值,于是我们可以取对数。

    [lg left(1 - dfrac{1}{2^{M + 1}} ight) + (2^E - 1) lg 2 = lg A + B ]

    然而取对数之后算出来结果太小,误差很大,AC不了。所以我们还要用些其他技巧。

    设式子左边的值为 (res),则 (10^{res} = C imes 10^D) ,其中 (0 < C < 10)
    显然 (0 < lg C < 1),所以 (D = lfloor res floor) , $ C = 10 ^ {res - D}$ 。
    比较一下 (A)(C)(B)(D) 即可。

    顺带一提,记得用sscanf输入,注意$ eps $ 不能取太小,$ 10^{-4} $ 即可。

    #include <cstdio>
    #include <cstring>
    #include <cmath>
    
    #define MAX_M (9 + 5)
    #define MAX_E (30 + 5)
    
    using namespace std;
    
    const double eps = 1e-4;
    const double lg2 = log10(2);
    double A;
    int B;
    int b[MAX_M][MAX_E];
    double a[MAX_M][MAX_E];
    char s[100];
    
    int main()
    {
    	double res;
    	for (int M = 0; M <= 9; ++M)
    	{
    		for (int E = 1; E <= 30; ++E)
    		{
    			res = log10(1.0 - 1.0 / (1 << M + 1)) + ((1 << E) - 1) * lg2;
    			b[M][E] = (int)res;
    			a[M][E] = pow(10, res - b[M][E]);
    		}
    	}
    	while (scanf("%s", s))
    	{
    		*strchr(s, 'e') = ' ';
    		sscanf(s, "%lf %d", &A, &B);
    		if (!A && !B) break;
    		for (int M = 0; M <= 9; ++M)
    		{
    			for (int E = 1; E <= 30; ++E)
    			{
    				if (b[M][E] != B || a[M][E] - A > eps || a[M][E] - A < -eps) continue;
    				printf("%d %d
    ", M, E);
    				goto NEXT;
    			}
    		}
    		NEXT:;
    	}
    	return 0;
    }
    
  • 相关阅读:
    Winefish-GTK LaTeX 编辑器
    GPuTTY:SSH 会话治理器
    Zudeo──高清版 Youtube
    HardInfo-体系信息搜集对象
    Liferea 1.2.0 正式版
    HomeBank:家庭理财软件
    ParolaPass:暗码天生器
    VLC Media Player 0.8.6
    流程图的绘制方法
    Delphi 2009 中的匿名方法(reference to)
  • 原文地址:https://www.cnblogs.com/kcn999/p/13195145.html
Copyright © 2011-2022 走看看