这是一道很考验数学素质的一道题目。但是作为一名优秀每天划水的OIer,这道题是不难的。来看我的分析:
因为数字很大,因此我们可以求以10为底的对数:lgv=lg(xM+1−1)−(M+)×lg2+(2E−1)×lg2=lgA+B。
根据题意可以推算出最大值vmax=(1−2M+11)×22E−1=A×10B。
然后我们遍历所有可能的M,根据上面推导出来的公式求E的值,然后再利用E和M求出lgv和输入的值进行比较,如果相等,说明M和E就是所求的值。做两个浮点数相等判断的时候,我们需要设置一个误差常量eps,具体大小要根据具体的题目来定。
完整的程序(c++11
)如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| #include <bits/stdc++.h> using namespace std; const double EPS=1e-6; int main(void) { char line[256]; double lg2=log10(2),a,v; int b; while(scanf("%s",line)==1&&strcmp(line,"0e0")!=0) { *strchr(line,'e')=' '; sscanf(line,"%lf%d",&a,&b); v=log10(a)+b; for(int m=1;m<=10;++m) { int mhe=round(log10((v+m*lg2-log10(pow(2,m)-1))/lg2+1)/lg2); if(fabs(((1<<mhe)-1)*lg2+log10(pow(2,m)-1)-m*lg2-v)<=EPS) { printf("%d %d\n",m-1,mhe); break; } } } return 0; }
|