2017蓝桥杯Excel地址(C++C组)

题目:Excel地址


Excel单元格的地址表示很有趣,它使用字母来表示列号。
比如,
A表示第1列,
B表示第2列,
Z表示第26列,
AA表示第27列,
AB表示第28列,
BA表示第53列,
....


当然Excel的最大列号是有限度的,所以转换起来不难。
如果我们想把这种表示法一般化,可以把很大的数字转换为很长的字母序列呢?


本题目既是要求对输入的数字, 输出其对应的Excel地址表示方式。


例如,
输入:
26
则程序应该输出:
Z


再例如,
输入:
2054
则程序应该输出:
BZZ


我们约定,输入的整数范围[1,2147483647]


资源约定:
峰值内存消耗(含虚拟机) < 256M
CPU消耗  < 1000ms




请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。


注意:
main函数需要返回0;
只使用ANSI C/ANSI C++ 标准;
不要调用依赖于编译环境或操作系统的特殊函数。
所有依赖的函数必须明确地在源文件中 #include <xxx>
不能通过工程设置而省略常用头文件。


提交程序时,注意选择所期望的语言类型和编译器类型。


------------------------------


笨笨有话说:
    这有点像进制关系,又不完全是。好像末2位是以1当26,末3位是以1当26*26


歪歪有话说:

    要是从字母序列转数字还好点,倒过来有点麻烦,不过计算机跑得快啊。


解析:

初读这道题,感觉挺简单的,不就是自定义一个进制系统么?后来才发现,我太低估这道题了。为什么说低估它了呢,听我细细到来.首先,按照我们传统的对二进制,八进制,十进制,十六进制数的传统思维做这道题,会陷入一个恶性循环的思维,这是这道题最大的难点,因为,你要注意到如果让你表示十进制的10和这道题的第27列,你怎么完成这个思维的过度呢,首先10是一个两位数,拆分为1和0,他们不一样,而用这道题的正确答案来表示27列是AA,拆分为A和A,他们一样,有人说,我用Z来表示在这道题中的进制系统中和十进制系统中10同样的地位(有人这听不懂了,这是一个思维过度,多看几遍,用笔划一下,就知道我说啥了),可是,10是双位数,Z是单位数. 以上的两种解法采取哪种合适呢,看题目,题目中说A表示1,AA表示27,并且有26个字母,恰好1 + 26 = 27,所以,我们果断选择第二种思维,同时也决定了,这道题采用的进制系统为26进制系统,但是我们在第二种方法还遗留了一个问题,更何况我们早已习惯二进制,八进制,十六进制,十进制系统中都有0的传统思维,这两个问题该怎么解决呢?一个办法,等效替代法,我们可以把Z看为进位的26(十进制系统中的10),并在主观上就认为Z是26进制系统中最小的两位数,Z就等效为A0即26 * 1 + 0 = 26,注意,这点尤为重要,而且必须理解,因为,该题没有给出表示第0列的标志,但是我们根深蒂固的思想导致很难处理没有0的其他进制系统的运算,所以,我们这里采用这样的做法这是这道题解的核心。下面给出数据对照表,方便大家更直观的理解本题的26进制系统:


源码:

#include<iostream>


using namespace std;


#define SUB 50
int sign[SUB] = {0};
int get_digits(int data);
void init_data(int data);
void view(int data[]);
void jud(int data);


int info;


int main(int argc,char** argv){

while(1){

printf(" ");
cin >> info;
init_data(info);
jud(info);
}


}


void jud(int data){

bool state = true;

for(int i = 0;i < get_digits(data);i++){

if(sign[i] == 0){

state = false;
}
}

if(state){

view(sign);

}else{

if(data == 26){

cout << "Z";

}else{

for(int i = get_digits(data) - 1;i >= 0;i--){

if(sign[i] == 0){

sign[i - 1] = sign[i - 1] - 1;
sign[i] = 26;
}
}

view(sign);
}
}
}


void init_data(int data){

int sub = 0;
int sub_temp = get_digits(data);

while(data){

sign[sub_temp - 1 - sub] = data % 26;
data = data / 26;
sub++;
}
}


int get_digits(int data){

int order = 1;

while(data / 26){

data = data / 26;
order++;
}

return order;
}


void view(int data[]){

for(int i = 0;i < get_digits(info);i++){

switch(data[i]){

case 1:
cout << "A";
break;
case 2:
cout << "B";
break;
case 3:
cout << "C";
break;
case 4:
cout << "D";
break;
case 5:
cout << "E";
break;
case 6:
cout << "F";
break;
case 7:
cout << "G";
break;
case 8:
cout << "H";
break;
case 9:
cout << "I";
break;
case 10:
cout << "J";
break;
case 11:
cout << "K";
break;
case 12:
cout << "L";
break;
case 13:
cout << "M";
break;
case 14:
cout << "N";
break;
case 15:
cout << "O";
break;
case 16:
cout << "P";
break;
case 17:
cout << "Q";
break;
case 18:
cout << "R";
break;
case 19:
cout << "S";
break;
case 20:
cout << "T";
break;
case 21:
cout << "U";
break;
case 22:
cout << "V";
break;
case 23:
cout << "W";
break;
case 24:
cout << "X";
break;
case 25:
cout << "Y";
break;
case 26:
cout << "Z";
break;
case 0:
cout << "Z";
default:
break;
}
}
}








原文地址:https://www.cnblogs.com/viplanyue/p/12700747.html