本题涉及大数加法、大数乘法、大数除法的运用,套用大数模板即可,转换为一个 26 进制数的转化问题。
单词转化为数字:
Σ(字母排行(a为1, b为2…) * 26^(单词中此字母后面的字母个数)),例如 bc = 2*26^1 + 3*26^0 = 55;
数字转化为单词:
%26,/26,%26,/26…,例如 28%26==2 -> b,28/26==1,1%26==1 -> a,1/26==0,即 28 = ab,(如果余数为 0,则对应字母 z)
(用 C++ 写代码量比较大,在大数问题上 java 的 BigInteger 有天然优势)
#include <iostream>
#include <string>
#include <cctype>
#include <cstring>
#include <iomanip>
using namespace std;
int num[25][50]; //26的0次幂至19次幂
int temp[50], ans[50];
string word; //数字转化的单词
//初始化打表,依次计算26的0次幂至19次幂
void init()
{
num[0][0] = 1;
num[0][1] = 1;
num[1][0] = 2;
num[1][1] = 6; num[1][2] = 2;
int i, j;
for (i = 2; i < 20; i++) //大数乘法模板
{
int carry = 0;
for (j = 1; j <= num[i - 1][0]; j++)
{
num[i][j] = num[i - 1][j] * 26 + carry;
carry = num[i][j] / 10;
num[i][j] %= 10;
}
num[i][0] = num[i - 1][0];
while (carry > 0)
{
num[i][++num[i][0]] = carry % 10;
carry /= 10;
}
}
}
//大数乘法,计算n*26^row,结果保存至temp
void bigMul(int row, int n)
{
int carry = 0;
for (int i = 1; i <= num[row][0]; i++)
{
temp[i] = num[row][i] * n + carry;
carry = temp[i] / 10;
temp[i] %= 10;
}
temp[0] = num[row][0];
while (carry > 0)
{
temp[++temp[0]] = carry % 10;
carry /= 10;
}
}
//大数加法,计算ans+temp,结果保存至ans
void bigAdd()
{
if (ans[0] < temp[0])
ans[0] = temp[0];
int carry = 0;
for (int i = 1; i <= ans[0]; i++)
{
ans[i] = ans[i] + temp[i] + carry;
carry = ans[i] / 10;
ans[i] %= 10;
}
while (carry > 0)
{
ans[++ans[0]] = carry % 10;
carry /= 10;
}
}
//大数除法,计算temp/26的商和余数,商保存至temp
void bigDiv()
{
int d = 0; //当前被除数
for (int i = temp[0]; i > 0; i--)
{
d = d * 10 + temp[i];
temp[i] = d / 26;
d %= 26;
}
if (d != 0) //余数不为0
{
char c = 'a' + d - 1;
word = c + word;
}
else //余数为0
word = 'z' + word;
while (temp[temp[0]] == 0)
{
if (temp[0] == 1)
break;
--temp[0];
}
}
//输出用逗号分隔的数字
void output()
{
int first = ans[0] % 3; //第一个逗号之前的数的个数
int cnt = 0;
for (int i = ans[0]; i > 1; i--)
{
cout << ans[i];
++cnt;
if (cnt == first)
cout << ",";
else if ((cnt - first) % 3 == 0)
cout << ",";
}
cout << ans[1] << endl;
}
int main()
{
init();
string s;
while (cin >> s)
{
if (s == "*")
break;
else if (islower(s[0])) //输入为单词
{
memset(ans, 0, sizeof(ans));
int len = s.size();
for (int i = 0; i < len; i++)
{
memset(temp, 0, sizeof(temp));
bigMul(len - 1 - i, s[i] - 'a' + 1);
bigAdd();
}
cout << setw(22) << setiosflags(ios::left) << setfill(' ') << s;
output();
}
else //输入为数字
{
word = "";
memset(ans, 0, sizeof(ans));
memset(temp, 0, sizeof(temp));
int len = s.size();
ans[0] = len;
temp[0] = len;
for (int i = 0; i < len; i++)
{
ans[len - i] = s[i] - '0';
temp[len - i] = s[i] - '0';
}
while (temp[0] != 1 || temp[1] != 0)
{
bigDiv();
}
cout << setw(22) << setiosflags(ios::left) << setfill(' ') << word;
output();
}
}
return 0;
}
继续加油。