首页 > 代码库 > HDU 1314 Numerically Speaking(大数加减乘除+另类二十六进制互相转换)

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代码:
技术分享
  1 # include <stdio.h>
  2 # include <string.h>
  3 # include <stdlib.h>
  4 # include <iostream>
  5 # include <fstream>
  6 # include <vector>
  7 # include <queue>
  8 # include <stack>
  9 # include <map>
 10 # include <math.h>
 11 # include <algorithm>
 12 using namespace std;
 13 # define pi acos(-1.0)
 14 # define mem(a,b) memset(a,b,sizeof(a))
 15 # define FOR(i,a,n) for(int i=a; i<=n; ++i)
 16 # define For(i,n,a) for(int i=n; i>=a; --i)
 17 # define FO(i,a,n) for(int i=a; i<n; ++i)
 18 # define Fo(i,n,a) for(int i=n; i>a ;--i)
 19 typedef long long LL;
 20 typedef unsigned long long ULL;
 21 
 22 //string比较函数:相等返回0,str1>str2返回1,str1<str2返回-1.
 23 int Compare(string str1,string str2)
 24 {
 25     if(str1.length() > str2.length()) return 1;
 26     else if(str1.length() < str2.length()) return -1;
 27     else return str1.compare(str2);
 28 }
 29 
 30 string Big_Plus(string str1,string str2)
 31 {
 32     string ans;
 33     int len1=str1.length();
 34     int len2=str2.length();
 35     //将长度较小的前面补0,使两个string长度相同
 36     if(len1<len2){
 37         for(int i=1;i<=len2-len1;i++){
 38             str1="0"+str1;
 39         }
 40     }else {
 41         for(int i=1;i<=len1-len2;i++){
 42             str2="0"+str2;
 43         }
 44     }
 45     int len=max(len1,len2);
 46     int carry=0;
 47     for(int i=len-1;i>=0;i--){
 48         int tmp=str1[i]-0+str2[i]-0+carry;
 49         carry=tmp/10;
 50         tmp%=10;
 51         ans=char(tmp+0)+ans;
 52     }
 53     if(carry) ans=char(carry+0)+ans;
 54     return ans;
 55 }
 56 
 57 //支持大数减小数
 58 string Big_Sub(string str1,string str2)
 59 {
 60     string ans;
 61     int carry=0;
 62     int difference=str1.length()-str2.length();//长度差
 63     for(int i=str2.length()-1;i>=0;i--){
 64         if(str1[difference+i]<str2[i]+carry){
 65             ans=char(str1[difference+i]+10-str2[i]-carry+0)+ans;
 66             carry=1;
 67         }else {
 68             ans=char(str1[difference+i]-str2[i]-carry+0)+ans;
 69             carry=0;
 70         }
 71     }
 72     for(int i=difference-1;i>=0;i--){
 73         if(str1[i]-carry>=0){
 74             ans=char(str1[i]-carry)+ans;
 75             carry=0;
 76         }else {
 77             ans=char(str1[i]-carry+10)+ans;
 78             carry=1;
 79         }
 80     }
 81     //去除前导0
 82     ans.erase(0,ans.find_first_not_of(0));
 83     if(ans.empty()) ans="0";
 84     return ans;
 85 }
 86 
 87 string Big_Mul(string str1,string str2)
 88 {
 89     string ans;
 90     int len1=str1.length();
 91     int len2=str2.length();
 92     for(int i=len2-1;i>=0;i--){
 93         string tmpstr="";
 94         int data=http://www.mamicode.com/str2[i]-0;
 95         int carry=0;
 96         if(data!=0){
 97             for(int j=1;j<=len2-1-i;j++){
 98                 tmpstr+="0";
 99             }
100             for(int j=len1-1;j>=0;j--){
101                 int t=data*(str1[j]-0)+carry;
102                 carry=t/10;
103                 t%=10;
104                 tmpstr=char(t+0)+tmpstr;
105             }
106             if(carry!=0) tmpstr=char(carry+0)+tmpstr;
107         }
108         ans=Big_Plus(ans,tmpstr);
109     }
110     ans.erase(0,ans.find_first_not_of(0));
111     if(ans.empty()) ans="0";
112     return ans;
113 }
114 
115 //正数相除,商为quotient,余数为residue
116 
117 void Big_Div(string str1,string str2,string& quotient,string& residue)
118 {
119     quotient=residue="";//商和余数清空
120     if(str2=="0"){//;判断除数是否为0
121         quotient=residue="ERROR";
122         return;
123     }
124     if(str1=="0"){//判断被除数是否为0
125         quotient=residue="0";
126         return;
127     }
128     int res=Compare(str1,str2);
129     if(res<0){//被除数小于除数
130         quotient="0";
131         residue=str1;
132         return;
133     }else if(res==0){
134         quotient="1";
135         residue="0";
136         return ;
137     }else {
138         int len1=str1.length();
139         int len2=str2.length();
140         string tmpstr;
141         tmpstr.append(str1,0,len2-1);//将str1的前len2位赋给tmpstr
142         for(int i=len2-1;i<len1;i++){
143             tmpstr=tmpstr+str1[i];//被除数新补充一位
144             tmpstr.erase(0,tmpstr.find_first_not_of(0));//去除前导0
145             if(tmpstr.empty()) tmpstr="0";
146             for(char ch=9;ch>=0;ch--){//试商
147                 string tmp,ans;
148                 tmp=tmp+ch;
149                 ans=Big_Mul(str2,tmp);//计算乘积
150                 if(Compare(ans,tmpstr)<=0){//试商成功
151                     quotient=quotient+ch;
152                     tmpstr=Big_Sub(tmpstr,ans);//减掉乘积
153                     break;
154                 }
155             }
156         }
157         residue=tmpstr;
158     }
159     quotient.erase(0,quotient.find_first_not_of(0));
160     if(quotient.empty()) quotient="0";
161 }
162 
163 string change(int num)
164 {
165     string n="";
166     stack<char>M;
167     while(num>0)
168     {
169         M.push(num%10+0);
170         num/=10;
171     }
172     while(!M.empty())
173     {
174         n+=M.top();
175         M.pop();
176     }
177     return n;
178 }
179 
180 int change(string num)
181 {
182     int n=num[0]-0;
183     for(int i=1;i<num.size();i++)
184         n=n*10+num[i]-0;
185     return n;
186 }
187 
188 int main()
189 {
190     //freopen("in.txt", "r", stdin);
191     string s;
192     while(cin>>s,s[0]!=*)
193     {
194         if(a<=s[0]&&s[0]<=z)
195         {
196             string num=change(s[0]-a+1);
197             for(int i=1;i<s.size();i++)
198             {
199                 num=Big_Plus(Big_Mul(num,change(26)),change(s[i]-a+1));
200             }
201             cout<<s;
202             for(int i=s.size()+1;i<23;i++)cout<< ;
203             for(int i=0;i<num.size();i++)
204             {
205                 if(i)
206                     printf((num.size()-i)%3==0?",%c":"%c",num[i]);
207                 else
208                     printf("%c",num[i]);
209             }
210             cout<<endl;
211         }
212         else if(0<=s[0]&&s[0]<=9)
213         {
214             stack<char>M;
215             string str1,str2;//商和余数
216             string str="",str3=s;
217             while(Compare(str3,"0")>0)//str1>0
218             {
219                 Big_Div(str3,"26",str1,str2);
220                 str3=str1;
221                 if(str2=="0")
222                 {
223                     M.push(z);
224                     str3=Big_Sub(str3,"1");
225                 }
226                 else
227                 {
228                     M.push(change(str2)+a-1);
229                 }
230             }
231             while(!M.empty())
232             {
233                 str+=M.top();
234                 M.pop();
235             }
236             cout<<str;
237             for(int i=str.size()+1;i<23;i++)cout<< ;
238             for(int i=0;i<s.size();i++)
239             {
240                 if(i)
241                     printf((s.size()-i)%3==0?",%c":"%c",s[i]);
242                 else
243                     printf("%c",s[i]);
244             }
245             cout<<endl;
246         }
247     }
248     return 0;
249 }
View Code

 

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