[蓝桥杯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.