地址转换
题目描述
Excel 是最常用的办公软件。每个单元格都有唯一的地址表示。比如:第 12 行第 4 列表示为:"D12",第 5 行第 255 列表示为"IU5"。
事实上,Excel 提供了两种地址表示方法,还有一种表示法叫做 RC 格式地址。第 12 行第 4 列表示为:"R12C4",第 5 行第 255 列表示为"R5C255"。
你的任务是:编写程序,实现从 RC 地址格式到常规地址格式的转换。
输入描述
用户先输入一个整数 n (n<100)n (n<100),表示接下来有 nn 行输入数据。
接着输入的 nn 行数据是 RC 格式的 Excel 单元格地址表示法。
输出描述
程序则输出 nn 行数据,每行是转换后的常规地址表示法。
输入输出样例
示例
输入
用户输入:
2
R12C4
R5C255
输出
D12
IU5
运行限制
- 最大运行时间:1s
- 最大运行内存: 256M
总通过次数: 1194 | 总提交次数: 1232 | 通过率: 96.9%
难度: 中等 标签: 2012, 模拟, 国赛
Excel地址转换算法解析与实现
📌 问题分析
需要将Excel的RC地址格式(如"R12C4")转换为常规地址格式(如"D12")。核心在于将列号数字转换为字母序列(类似26进制转换),行号直接保留。转换规则如下:
- 列号转换:数字列号需转换为字母组合(1→A, 2→B, ..., 26→Z, 27→AA等)
- 特殊规则:Excel列号从1开始(非0),当列号为26的倍数时需特殊处理(如26→Z, 52→AZ)
⚙️ 转换算法步骤
- 解析输入:提取行号(R后数字)和列号(C后数字)
- 示例:"R12C4" → 行号=12, 列号=4
- 列号转字母:
while 列号 > 0: 余数 = (列号 - 1) % 26 # 映射到0-25范围 当前字母 = chr(65 + 余数) # 65是'A'的ASCII 列号 = (列号 - 1) // 26 字母序列 = 当前字母 + 字母序列 # 逆序拼接
- 组合结果:字母序列 + 行号字符串
🌰 关键案例验证
RC格式 | 列号计算过程 | 常规格式 |
---|---|---|
R1C1 | 1→(0)%26→A | A1 |
R5C255 | 255→(254%26=20→U)→(9→I)→IU | IU5 |
R255C27 | 27→(26%26=0→A)→(1-1=0→A)→AA | AA255 |
R100C100 | 100→(99%26=21→V)→(3→C)→CV | CV100 |
⚡ C++ 代码实现
#include <iostream>
#include <string>
using namespace std;
int main() {
int n;
cin >> n;
cin.ignore(); // 清除输入缓冲区
for (int i = 0; i < n; i++) {
string s;
getline(cin, s);
// 解析行号和列号
size_t posC = s.find('C');
string row_str = s.substr(1, posC - 1);
int col = stoi(s.substr(posC + 1));
// 列号转字母序列
string col_letters = "";
while (col > 0) {
int r = (col - 1) % 26;
col_letters = char('A' + r) + col_letters;
col = (col - 1) / 26;
}
// 输出结果
cout << col_letters << row_str << endl;
}
return 0;
}
⏱️ 性能与边界处理
- 时间复杂度:O(n×k),n≤100,k为列号转换循环次数(最大约log₂₆(16384)=3次)
- 边界案例:
- 列号26 →
Z
(非A@
) - 列号52 →
AZ
(52-1=51 → 51%26=25→Z → 51/26=1 → 1-1=0→A →AZ
)6
- 列号26 →
- 输入处理:使用
getline()
避免空格干扰,stoi()
自动处理数字前缀