• HDU 1314 Numerically Speaking(大数加减乘除+另类二十六进制互相转换)


    原题代号:HDU 1314

    原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1314

    Numerically Speaking

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
    Total Submission(s): 766    Accepted Submission(s): 190

    Problem Description
    A developer of crossword puzzles (and other similar word games) has decided to develop a mapping between every possible word with from one to twenty characters and unique integers. The mapping is very simple, with the ordering being done first by the length of the word, and then alphabetically. Part of the list is shown below.
    a 1
    b 2
    ...
    z 26
    aa 27
    ab 28
    ...
    snowfall 157,118,051,752
    ...

    Your job in this problem is to develop a program which can translate, bidirectionally, between the unique word numbers and the corresponding words.
     
    Input
    Input to the program is a list of words and numbers, one per line starting in column one, followed by a line containing a single asterisk in column one. A number will consist only of decimal digits (0 through 9) followed immediately by the end of line (that is, there will be no commas in input numbers). A word will consist of between one and twenty lowercase alphabetic characters (a through z).
     
    Output
    The output is to contain a single line for each word or number in the input data. This line is to contain the word starting in column one, followed by an appropriate number of blanks, and the corresponding word number starting in column 23. Word numbers that have more than three digits must be separated by commas at thousands, millions, and so forth.
     
    Sample Input

    29697684282993
    transcendental
    28011622636823854456520
    computationally
    zzzzzzzzzzzzzzzzzzzz
    *

     
    Sample Output

    elementary 29,697,684,282,993
    transcendental 51,346,529,199,396,181,750
    prestidigitation 28,011,622,636,823,854,456,520
    computationally 232,049,592,627,851,629,097
    zzzzzzzzzzzzzzzzzzzz 20,725,274,851,017,785,518,433,805,270

    (注意:数字是从第23列开始写,之前空格不能丢了)

    解题思路:这个题类似二十六进制的互相转换,只不过a相当于1,z相当于26而已;只不过要考虑数字转换成字母时的特殊地方(26/26=1余0,但是26是z,所以如果余数为0则字母为z并且商-=1)
    AC代码:
    # include <stdio.h>
    # include <string.h>
    # include <stdlib.h>
    # include <iostream>
    # include <fstream>
    # include <vector>
    # include <queue>
    # include <stack>
    # include <map>
    # include <math.h>
    # include <algorithm>
    using namespace std;
    # define pi acos(-1.0)
    # define mem(a,b) memset(a,b,sizeof(a))
    # define FOR(i,a,n) for(int i=a; i<=n; ++i)
    # define For(i,n,a) for(int i=n; i>=a; --i)
    # define FO(i,a,n) for(int i=a; i<n; ++i)
    # define Fo(i,n,a) for(int i=n; i>a ;--i)
    typedef long long LL;
    typedef unsigned long long ULL;
    
    //string比较函数:相等返回0,str1>str2返回1,str1<str2返回-1.
    int Compare(string str1,string str2)
    {
        if(str1.length() > str2.length()) return 1;
        else if(str1.length() < str2.length()) return -1;
        else return str1.compare(str2);
    }
    
    string Big_Plus(string str1,string str2)
    {
        string ans;
        int len1=str1.length();
        int len2=str2.length();
        //将长度较小的前面补0,使两个string长度相同
        if(len1<len2){
            for(int i=1;i<=len2-len1;i++){
                str1="0"+str1;
            }
        }else {
            for(int i=1;i<=len1-len2;i++){
                str2="0"+str2;
            }
        }
        int len=max(len1,len2);
        int carry=0;
        for(int i=len-1;i>=0;i--){
            int tmp=str1[i]-'0'+str2[i]-'0'+carry;
            carry=tmp/10;
            tmp%=10;
            ans=char(tmp+'0')+ans;
        }
        if(carry) ans=char(carry+'0')+ans;
        return ans;
    }
    
    //支持大数减小数
    string Big_Sub(string str1,string str2)
    {
        string ans;
        int carry=0;
        int difference=str1.length()-str2.length();//长度差
        for(int i=str2.length()-1;i>=0;i--){
            if(str1[difference+i]<str2[i]+carry){
                ans=char(str1[difference+i]+10-str2[i]-carry+'0')+ans;
                carry=1;
            }else {
                ans=char(str1[difference+i]-str2[i]-carry+'0')+ans;
                carry=0;
            }
        }
        for(int i=difference-1;i>=0;i--){
            if(str1[i]-carry>='0'){
                ans=char(str1[i]-carry)+ans;
                carry=0;
            }else {
                ans=char(str1[i]-carry+10)+ans;
                carry=1;
            }
        }
        //去除前导0
        ans.erase(0,ans.find_first_not_of('0'));
        if(ans.empty()) ans="0";
        return ans;
    }
    
    string Big_Mul(string str1,string str2)
    {
        string ans;
        int len1=str1.length();
        int len2=str2.length();
        for(int i=len2-1;i>=0;i--){
            string tmpstr="";
            int data=str2[i]-'0';
            int carry=0;
            if(data!=0){
                for(int j=1;j<=len2-1-i;j++){
                    tmpstr+="0";
                }
                for(int j=len1-1;j>=0;j--){
                    int t=data*(str1[j]-'0')+carry;
                    carry=t/10;
                    t%=10;
                    tmpstr=char(t+'0')+tmpstr;
                }
                if(carry!=0) tmpstr=char(carry+'0')+tmpstr;
            }
            ans=Big_Plus(ans,tmpstr);
        }
        ans.erase(0,ans.find_first_not_of('0'));
        if(ans.empty()) ans="0";
        return ans;
    }
    
    //正数相除,商为quotient,余数为residue
    
    void Big_Div(string str1,string str2,string& quotient,string& residue)
    {
        quotient=residue="";//商和余数清空
        if(str2=="0"){//;判断除数是否为0
            quotient=residue="ERROR";
            return;
        }
        if(str1=="0"){//判断被除数是否为0
            quotient=residue="0";
            return;
        }
        int res=Compare(str1,str2);
        if(res<0){//被除数小于除数
            quotient="0";
            residue=str1;
            return;
        }else if(res==0){
            quotient="1";
            residue="0";
            return ;
        }else {
            int len1=str1.length();
            int len2=str2.length();
            string tmpstr;
            tmpstr.append(str1,0,len2-1);//将str1的前len2位赋给tmpstr
            for(int i=len2-1;i<len1;i++){
                tmpstr=tmpstr+str1[i];//被除数新补充一位
                tmpstr.erase(0,tmpstr.find_first_not_of('0'));//去除前导0
                if(tmpstr.empty()) tmpstr="0";
                for(char ch='9';ch>='0';ch--){//试商
                    string tmp,ans;
                    tmp=tmp+ch;
                    ans=Big_Mul(str2,tmp);//计算乘积
                    if(Compare(ans,tmpstr)<=0){//试商成功
                        quotient=quotient+ch;
                        tmpstr=Big_Sub(tmpstr,ans);//减掉乘积
                        break;
                    }
                }
            }
            residue=tmpstr;
        }
        quotient.erase(0,quotient.find_first_not_of('0'));
        if(quotient.empty()) quotient="0";
    }
    
    string change(int num)
    {
        string n="";
        stack<char>M;
        while(num>0)
        {
            M.push(num%10+'0');
            num/=10;
        }
        while(!M.empty())
        {
            n+=M.top();
            M.pop();
        }
        return n;
    }
    
    int change(string num)
    {
        int n=num[0]-'0';
        for(int i=1;i<num.size();i++)
            n=n*10+num[i]-'0';
        return n;
    }
    
    int main()
    {
        //freopen("in.txt", "r", stdin);
        string s;
        while(cin>>s,s[0]!='*')
        {
            if('a'<=s[0]&&s[0]<='z')
            {
                string num=change(s[0]-'a'+1);
                for(int i=1;i<s.size();i++)
                {
                    num=Big_Plus(Big_Mul(num,change(26)),change(s[i]-'a'+1));
                }
                cout<<s;
                for(int i=s.size()+1;i<23;i++)cout<<' ';
                for(int i=0;i<num.size();i++)
                {
                    if(i)
                        printf((num.size()-i)%3==0?",%c":"%c",num[i]);
                    else
                        printf("%c",num[i]);
                }
                cout<<endl;
            }
            else if('0'<=s[0]&&s[0]<='9')
            {
                stack<char>M;
                string str1,str2;//商和余数
                string str="",str3=s;
                while(Compare(str3,"0")>0)//str1>0
                {
                    Big_Div(str3,"26",str1,str2);
                    str3=str1;
                    if(str2=="0")
                    {
                        M.push('z');
                        str3=Big_Sub(str3,"1");
                    }
                    else
                    {
                        M.push(change(str2)+'a'-1);
                    }
                }
                while(!M.empty())
                {
                    str+=M.top();
                    M.pop();
                }
                cout<<str;
                for(int i=str.size()+1;i<23;i++)cout<<' ';
                for(int i=0;i<s.size();i++)
                {
                    if(i)
                        printf((s.size()-i)%3==0?",%c":"%c",s[i]);
                    else
                        printf("%c",s[i]);
                }
                cout<<endl;
            }
        }
        return 0;
    }
  • 相关阅读:
    spring mvc 返回json
    spring mvc 解决后台传递值乱码问题
    sring mvc 返回值至jsp界面的几种方式
    spring mvc 注解访问控制器以及接收form数据的方式,包括直接接收日期类型及对象的方法
    spring mvc 通过配置xml访问控制器的三种方式
    spring mvc 入门配置
    HBase 学习笔记
    Centos搭建Linux测试环境,几个基本的设置项
    kafka 集群安装与安装测试
    Kafka 分布式消息队列介绍
  • 原文地址:https://www.cnblogs.com/teble/p/7224597.html
Copyright © 2020-2023  润新知