• HDU 1230解题报告


    Problem Description
    读入两个不超过25位的火星正整数A和B,计算A+B。需要注意的是:在火星上,整数不是单一进制的,第n位的进制就是第n个素数。例如:地球上的10进制数2,在火星上记为“1,0”,因为火星个位数是2进制的;地球上的10进制数38,在火星上记为“1,1,1,0”,因为火星个位数是2进制的,十位数是3进制的,百位数是5进制的,千位数是7进制的……

    Input
    测试输入包含若干测试用例,每个测试用例占一行,包含两个火星正整数A和B,火星整数的相邻两位数用逗号分隔,A和B之间有一个空格间隔。当A或B为0时输入结束,相应的结果不要输出。

    Output
    对每个测试用例输出1行,即火星表示法的A+B的值。

    Sample Input
    1,0 2,1
    4,2,0 1,2,0
    1 10,6,4,2,1
    0 0

    Sample Output
    1,0,1
    1,1,1,0
    1,0,0,0,0,0

    此题不是一道难题,但是所涉及知识点较多:

    1. 字符串处理
    2. 质数
    3. 大数加法

    在求质数方面,此题涉及到不超过30位,故可以使用打表,直接定义数组,在此不赘述。

    加法方面,必定涉及到进位问题,因此需要从低位到高位进行加法运算,因此第一步需要进行字符串反转。

    加法方面需要一位一位取出a,b中对应的数值,则设立ai,bi分别对a,b进行循环。此时需要考虑到a,b位数不对等的状况,因此在循环中必须有防止溢出的措施,当a[ai]=’’时,则终止ai 继续增加。而在取出每一位火星数中,一位火星数可能包含多个十进制位数,此时则需要一个循环,并设立aj,bj记录十进制位数,取出的结果放入atemp,btemp用于记录。
    在进行加法时还需要考虑进位问题,设置sign用于记录进位。

    代码如下

    #include<stdio.h>
    #include<math.h>
    void pirmes(int pri[]);
    int turnover(char str[]);
    int sum(char a[],int la,char b[],int lb);
    int main()
    {
        int la,lb;
        char a[100],b[100];
        while(scanf("%s %s",&a,&b)!=EOF &&  //a,b不能为0
              ( (a[1]==',' || a[0]!='0') && //若a[1]存在,号说明存在高位,则不会为0
               (b[1]==',' || b[0]!='0')){
            la=turnover(a);
            lb=turnover(b);
            sum(a,la,b,lb);
        }
    }
    
    void pirmes(int pri[]){ //求质数,将结果保存到pri[]中
        int n,i,j,sign;
        pri[0]=2;
        n=1;
        for(i=3;n<31;i+=2){
            sign=1;
            for(j=3;j<sqrt(i)+1;j+=2)
            {
                if(i%j==0){
                    sign=0;
                    break;
                }
            }
            if(sign)
                pri[n++]=i;
        }
        return;
    }
    
    int turnover(char str[]){  //将读入的字符串进行反转,常规的方法
        int i,n,j;
        char temp[100];
        for(i=0;str[i]!='' && str[i]!=NULL;i++){
            temp[i]=str[i];
        }
        n=i-1;
        for(i=n,j=0;i>=0;i--){
            str[j++]=temp[i];
            //printf("%c",str[j-1]);
        }
        //printf("
    ");
        return n;
    }
    
    int sum(char a[],int la,char b[],int lb){  //求和
        int pri[30],ai,bi,aj,bj,atemp,btemp;//ai,bi用于对a,b进行遍历,aj,bj用于对a,b中一位火星数记其十进制位数,atemp,btemp分别记录一位火星数
        int nsum[40],ni,sign;
    
    
        pirmes(pri);
        ai=bi=ni=sign=0;
        while(a[ai]!='' || b[bi]!='' || sign!=0){   //对a,b字符串进行遍历
            aj=bj=atemp=btemp=0;
            if(a[ai]=='')                             //若遍历到结尾,则atemp返回0
                atemp=0;
            else
            {
                while(a[ai] != ','){                     //只要不为',',说明还是一位火星数,需要将其转化为对应十进制数
                    if(a[ai] == '')                    //若此时已经遍历到首位,则防止继续遍历造成溢出
                    {
                        ai--;
                        break;
                    }
                    //printf("a[%d]=%c,",ai,a[ai]);
                    atemp+=(a[ai]-48)*(int)pow((double)10,(double)aj++);            //记录一位火星数
    //                printf("atemp=%d,",atemp);
                    ai++;
    //                printf("ai=%d
    ",ai);
                }
                ai++;
            }
            if(b[bi]=='')
                btemp=0;
            else
            {
                while(b[bi] != ','){
                    if(b[bi] == '')
                    {
                        bi--;
                        break;
                    }
                    btemp+=(b[bi]-48)*(int)pow((double)10,(double)bj++);
                    bi++;
                }
                bi++;
            }
     //       printf("atemp=%d btemp=%d sign=%d pri[%d]=%d
    ",atemp,btemp,sign,ni,pri[ni]);
            nsum[ni]=(atemp+btemp+sign)%pri[ni];            //一位火星数求和
            sign=(atemp+btemp+sign)/pri[ni];                //进位
     //       printf("%d
    ",nsum[ni]);
            ni++;
        }
        while(--ni>=0){
            printf("%d",nsum[ni]);
            if(ni>0)
                printf(",");
            else
                printf("
    ");
        }
        return 0;
    }
  • 相关阅读:
    golang fmt用法举例
    golang init函数
    golang 定时器
    golang 如何判断变量的类型
    题目:IO多路复用版FTP
    Python模块——gevent 在协程学习中遇到的模块
    python入门三十二天——协程 异步IO数据库队列缓存
    java——第一天 变量,java的基础类型
    操作PPT模块 python-pptx
    python入门三十一天---多进程
  • 原文地址:https://www.cnblogs.com/cunchen/p/9464222.html
Copyright © 2020-2023  润新知