• HDU4814——数学,模拟进制转换


    本题围绕:数学公式模拟进制转换

    HDU4814 Golden Radio Base

    题目描述

    将一个十进制的非负整数转换成E(黄金分割数)进制的数

    输入

    不大于10^9的非负整数,处理到文件尾

    输出

    转换成的E进制数(可能含有小数)

    样例输入

    1
    2
    3
    6
    10

    样例输出

    1
    10.01
    100.01
    1010.0001
    10100.0101

    题目分析

    对于本题,要注意的点有:首先对于一个十进制的正数,我们是可以严格转换成一个E(黄金分割数)进制的数的,而不是涉及到约等于,例如10-base的n,可以转换成n*E^0(以下用E代表黄金分割数进制),此外本题给出的两个提示公式也是解题的关键,我们可以通过这两个公式得到如下两个公式:① E^n = E^n-1 + E^n-2, ② 2*E^n = E^n+1 + E^n-2,而本题的思路就是,建立一个数组a[]用于保存我们需要输出的最终答案,a[i]存放E的i次方的系数(就像是二进制一样),由于本题的输出可能包含小数,所以我们将数组的一半用于存放小数位的系数(E的-i次方位,因为通过两个公式我们得知,即使E的幂指数是负数公式仍然成立),同时我们通过计算得知E^50已经大于10^9,所以我们只要将数组开成100,且前50位存放小数点后的系数,后50位存放小数点前的系数,a[50]初始化时等于n(将50作为E的0次方位,正好对应我们上面讲到的10-base的n可以转换成E-base的n*E^0),而对于我们整个a[]数组,我们需要不断遍历它,一旦它满足任意位的系数大于1(可以用公式②将它的系数拆给两边的位),或者连续两个位系数大于等于1(可以用公式①将下一个位的系数加上前两个系数的小的那个值,而前两个系数则减去这个小的值)都可以用公式去进行优化,直到整个数组a[]中不能再由两个公式进行优化后,输出答案(输出时注意省略前导零和后续零,同时注意是否需要输出小数位)

    代码:

     1 #include<iostream>
     2 #include<stdio.h>
     3 #include<string.h>
     4 using namespace std;
     5 
     6 /*    
     7     E^n代表黄金分割数E的n次方幂 
     8     公式1:E^n = E^(n-1) + E^(n-2)
     9     公式1推广:n*E^n = n*E^(n-1) + n*E^(n-2) 
    10     公式2:2*E^n = E^(n+1) + E^(n-2)
    11 */
    12 int min(int a, int b){
    13     return a < b ? a : b;
    14 }
    15 
    16 int main(){
    17     int a[105];
    18     int n;
    19     while(scanf("%d", &n) != EOF){
    20         memset(a, 0, sizeof(a));
    21         a[50] = n;
    22         int flag = 1;
    23         while(flag){
    24             flag = 0;
    25             for(int i = 1; i <= 100; i++){
    26                 if(a[i] > 1){        //如果系数大于1则根据公式2将系数分给高位和低位的系数,直到本身系数为0或1 
    27                     a[i+1] += a[i]/2;
    28                     a[i-2] += a[i]/2;
    29                     a[i] %= 2;
    30                     flag = 1;        //一旦执行过这个步骤则说明高位和低位的系数发生变化,则可能出现系数大于1或连续1出现 
    31                 }
    32                 if(a[i-1] && a[i-2]){    //先调用公式1推广,将两个连续大于等于1的系数中的最小值附加给a[i] 
    33                     int temp = min(a[i-1], a[i-2]); 
    34                     a[i-1] -= temp;        
    35                     a[i-2] -= temp;
    36                     a[i] += temp;
    37 //                    a[i-1]--;            //这里有个问题就是如果写成注释里的代码TL超时 
    38 //                    a[i-2]--;
    39 //                    a[i]++;
    40                     flag = 1;        //一旦a[i]增加,则a[i]有可能大于1,或者与其他相邻的数构成了连续1的情况 
    41                 } 
    42             }
    43         }
    44         int point = 0;
    45         for(int i = 49; i >= 1; i--){
    46             if(a[i] == 1){
    47                 point = 1;
    48                 break;
    49             }
    50         }
    51         //输出时前导0和后缀0不输出,同时注意是否需要小数点
    52         int front = 0;
    53         int back = 0; 
    54         for(int i = 100; i >= 50; i--){
    55             if(a[i] == 0 && front == 0){        //省略前导零 
    56                 continue;
    57             }
    58             if(a[i] == 1) front = 1;
    59             printf("%d", a[i]);
    60         } 
    61         for(int i = 1; i <= 49; i++){            //找到末尾最后一个1的位置back记录 
    62             if(a[i] == 1){
    63                 back = i;
    64                 break;
    65             }
    66         } 
    67         if(point){
    68              printf(".");
    69              for(int i = 49; i >= back; i--) printf("%d", a[i]);
    70         } 
    71         printf("
    ");
    72     }
    73     return 0;
    74 } 
    如果有任何意见请在评论区积极留言
  • 相关阅读:
    jquery文件上传控件 Uploadify
    【jQuery】uploadify,实际开发案例【选择完文件点击上传才上传】
    StarUML2 建模工具全平台破解及license验证简要分析
    Error:Failed to resolve: com.afollestad:material-dialogs:
    Android studio Github 断开连接
    Crashlytics Android 异常报告统计管理
    Android Studio集成crashlytics后无法编译的问题
    Android studio启动后卡在refreshing gradle project
    Android项目源码分享
    Android开发案例
  • 原文地址:https://www.cnblogs.com/YLTFY1998/p/11363226.html
Copyright © 2020-2023  润新知