[蓝桥杯2017初赛]Excel地址
题目描述
Excel单元格的地址表示很有趣,它使用字母来表示列号。
比如,A表示第1列,B表示第2列,Z表示第26列,AA表示第27列,AB表示第28列,BA表示第53列,…
当然Excel的最大列号是有限度的,所以转换起来不难。
如果我们想把这种表示法一般化,可以把很大的数字转换为很长的字母序列呢?
本题目既是要求对输入的数字, 输出其对应的Excel地址表示方式。
输入
输入存在多组测试数据,对于每组测试数据输入一行包含一个整数
输入的整数范围[1,2147483647]
输出
对于每组测试数据:输出一行表示答案
样例输入
26 2054 |
样例输出
Z BZZ |
方法1:
每次将num的数-1,然后再取模、除26.
非递归写法:
# include <iostream>
typedef long long ll;
template <typename T>
void print(T num) {
int an[100];
int di = 0;
while (num) {
an[di++] = (num - 1) % 26;
num = (num - 1) / 26;
}
for (int i = di - 1; i >= 0; i--) {
putchar(an[i] + 'A');
}
}
int main() {
ll n;
while (std::cin >> n) {
print(n);
puts("");
}
return 0;
}
递归写法:
# include <iostream>
typedef long long ll;
template <typename T>
void print(T num) {
if (!num) {
return;
}
print((num - 1) / 26);
putchar((num - 1) % 26 + 'A');
}
int main() {
ll n;
while (std::cin >> n) {
print(n);
puts("");
}
return 0;
}
方法2:
每次对26取模,如果结果为0就将num-1, 同时该位对应的数为26。再将num除以26.
非递归写法:
# include <iostream>
typedef long long ll;
template <typename T>
void print(T num) {
int an[100];
int di = 0;
while (num) {
if (num % 26 == 0) {
an[di++] = 26;
num--;
} else {
an[di++] = num % 26;
}
num = num / 26;
}
for (int i = di - 1; i >= 0; i--) {
putchar(an[i] + 'A' - 1);
}
}
int main() {
ll n;
while (std::cin >> n) {
print(n);
puts("");
}
return 0;
}
递归写法:
# include <iostream>
typedef long long ll;
template <typename T>
void print(T num) {
if (!num) {
return;
}
if (num % 26) {
print(num / 26);
putchar(num % 26 + 'A' - 1);
} else {
num--;
print(num / 26);
putchar('Z');
}
}
int main() {
ll n;
while (std::cin >> n) {
print(n);
puts("");
}
return 0;
}
推荐使用方法1.