题目大意
题目中给出了两种表示位置的方法:
- Excel表示法:用大写字母
A
→
Z
A \to Z
A→Z表示列,数字表示行。
对于大写字母表示列:从右到左,第 i i i个字符的权值是 2 6 i − 1 26^{i-1} 26i−1,值是这个字母在大写字母表里的顺序 × \times ×权值,列数则是所有字母值之和。
例如,BC23表示第55行( 3 × 1 + 2 × 26 3 \times1+2 \times26 3×1+2×26)列第23行; - 坐标表示法:用数字表示坐标,行的值前加字符’R’,列前加字符’C’。例如R23C55表示第55列第23行。
现在给出一种形式的表示,让你转化成另一种。
解题思路
总所周知,这是一道模拟。
- 对于坐标表示法转化成Excel表示法,先提取出行和列的值,再将行的值转化成字符(和进制转换差不多);
- 对于Excel表示法转化成坐标表示法,先提取出行和列的值,再将行转化回数字就行了。
代码实现
#include <bits/stdc++.h>
using namespace std;
string s;
// 坐标表示法 --> Excel表示法
void f1() {
// 求出坐标
int _x = 0, y = 0, i;
for (i = 1; isdigit(s[i]); ++i) {
y = y * 10 + s[i] - '0';
}
// 接着上次的继续遍历
for (++i; i < s.size(); ++i) {
_x = _x * 10 + s[i] - '0';
}
// 将横坐标转化成字母的形式
string x = "";
while (_x) {
if (_x % 26 == 0) { // 特判'Z'
x += 'Z';
} else {
x += (char)(_x % 26 + 'A' - 1);
}
_x = _x / 26 - !(_x % 26 != 0);
}
reverse(x.begin(), x.end());
cout << x << y << '\n';
}
// Excel表示法 --> 坐标表示法
void f2() {
int x = 0, y = 0, i;
for (i = 0; isupper(s[i]); ++i) {
y = y * 26 + s[i] - 'A' + 1;
}
// 接着上次的继续遍历
for (; i < s.size(); ++i) {
x = x * 10 + s[i] - '0';
}
cout << 'R' << x << 'C' << y << '\n';
}
int main() {
int n;
cin >> n;
while (n--) {
cin >> s;
bool flag = false;
for (int i = 1; i < s.size(); ++i) {
// isdigit: 判断字符是否是数字字符
// isupper: 是否是大写字符
if (isdigit(s[i - 1]) && isupper(s[i])) { // 判断是否是坐标表示法
f1();
flag = true;
break;
}
}
if (!flag) {
f2();
}
}
return 0;
}
Goodbye,大家明天(可能是今天,可能是后天,可能是 n ( n ∈ Z ) n(n \in Z) n(n∈Z)天后)再见鸭~