原题代号: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=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 }