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=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 }

时间: 2024-11-09 00:52:59

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

【HDOJ】1314 Numerically Speaking

学了几天的Java了,终于独立A了一道大数计算.感觉还得练Java啊. 1 import java.util.Scanner; 2 import java.math.BigInteger; 3 import java.lang.StringBuilder; 4 5 public class Main { 6 public static void main(String[] args) { 7 Scanner cin = new Scanner(System.in); 8 while (cin.h

2014年百度之星程序设计大赛 - 初赛(第一轮) hdu Grids (卡特兰数 大数除法取余 扩展gcd)

题目链接 分析:打表以后就能发现时卡特兰数, 但是有除法取余. f[i] = f[i-1]*(4*i - 2)/(i+1); 看了一下网上的题解,照着题解写了下面的代码,不过还是不明白,为什么用扩展gcd, 不是用逆元吗.. 网上还有别人的解释,没看懂,贴一下: (a / b) % m = ( a % (m*b)) / b 笔者注:鉴于ACM题目特别喜欢M=1000000007,为质数: 当gcd(b,m) = 1, 有性质: (a/b)%m = (a*b^-1)%m, 其中b^-1是b模m的逆

hdu acm-1047 Integer Inquiry(大数相加)

Integer Inquiry Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 11678    Accepted Submission(s): 2936 Problem Description One of the first users of BIT's new supercomputer was Chip Diller. He ex

Python 迭代器&amp;生成器,装饰器,递归,算法基础:二分查找、二维数组转换,正则表达式,作业:计算器开发

本节大纲 迭代器&生成器 装饰器  基本装饰器 多参数装饰器 递归 算法基础:二分查找.二维数组转换 正则表达式 常用模块学习 作业:计算器开发 实现加减乘除及拓号优先级解析 用户输入 1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )等类似公式后,必须自己解析里面的(),+,-,*,/符号和公式,运算后得出结果,结果必须与真实的计算器所得出的结果一致 迭代器&

输入一棵二叉搜索树,现在要将该二叉搜索树转换成一个排序的双向链表。

一.问题描述 输入一棵二叉搜索树,现在要将该二叉搜索树转换成一个排序的双向链表.而且在转换的过程中,不能创建任何新的结点,只能调整树中的结点指针的指向来实现. 二.实现思路 在二叉搜索树中,每个结点都有两个分别指向其左.右子树的指针,左子树结点的值总是小于父结点的值,右子树结点的值总是大于父结点的值.而在双向链表中,每个结点也有两个指针,它们分别指向前一个结点和后一个结点.所以这两种数据结构的结点是一致,二叉搜索树之所以为二叉搜索树,双向链表之所以为双向链表,只是因为两个指针的指向不同而已 思路

HDU 5047 Sawtooth(大数优化+递推公式)

http://acm.hdu.edu.cn/showproblem.php?pid=5047 题目大意: 给n条样子像“m”的折线,求它们能把二维平面分成的面最多是多少. 解题思路: 我们发现直线1条:2平面:2直线:4平面:3直线:7平面......因为第n条直线要与前面n-1条直线都相交,才能使分的平面最多,则添加第n条直线,平面增加n个: 所以公式是面F = 2 + 2 + 3 + ......+ n = (1+n)*n/2 + 1 因为题目的是“M”的折线,一个“M”有4条线将平面分成2

hdu 1212 Big Number(大数取模)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1212 Big Number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 7083    Accepted Submission(s): 4884 Problem Description As we know, Big Number is

HDU 5465 Clarke and puzzle Nim游戏+二维树状数组

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5465 Clarke and puzzle Accepts: 42 Submissions: 269 Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) 问题描述 克拉克是一名人格分裂患者.某一天,有两个克拉克(aa和bb)在玩一个方格游戏. 这个方格是一个n*mn∗m的矩阵,每个格子里有一

HDU 1047 Integer Inquiry 大数相加 string解法

本题就是大数相加,题目都不用看了. 不过注意的就是HDU的肯爹输出,好几次presentation error了. 还有个特殊情况,就是会有空数据的输入case. #include <stdio.h> #include <vector> #include <string.h> #include <algorithm> #include <iostream> #include <string> #include <limits.h