码蹄集 - MT2051 · excel的烦恼
Posted Tisfy.
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了码蹄集 - MT2051 · excel的烦恼相关的知识,希望对你有一定的参考价值。
传送门
excel的烦恼
时间限制:1秒
空间限制:65535 KB
题目描述
你用过Excel嘛?
在excel中,第一列被标为 A,第二列为 B,以此类推,第26列为 Z。接下来为由两个字母构成的列号: 第27列为AA,第28列为 AB…在标为ZZ的列之后则由三个字母构成列号,如此类推。
行号为从1开始的整数。
单元格的坐标由列号和行号连接而成。比如,BC23表示位于第55列23行的单元格。
有时也会采用被称为RXCY的坐标系统,其中X与Y为整数,坐标(X,Y)直接描述了对应单元格的位置。比如,R23C55即为前面所述的单元格。
您的任务是编写一个程序,将所给的单元格坐标转换为另一种坐标系统下面的形式。
输入描述
第一行一个整数 T ( 1 ≤ T ≤ 1 0 5 ) T(1\\leq T\\leq 10^5) T(1≤T≤105)表示将有T次询问。
接下来T行,每行一个坐标。
输出T行,每行一个被转换的坐标。
输出描述
一个整数表示答案
样例一
输入
3
R12C3
AE32
BB11
输出
C12
R32C31
R11C54
备注
每个坐标都是正确的。保证输入输出数据均在int范围内。输入输出数据字母部分均为大写。
题目分析
其实也就两种情况:
- R12C3 (字母 数字 字母 数字)
- AE32 (字母 数字)
如果用“N”代表数字(Number),用“C”代表字母(Charater),那么上述两种情况可分别简记为:“CNCN”和“CN”
题目要求就是在上述两种情况之间转换。
输入属于上述的哪种情况也十分容易判断,我们只需要看是否存在数字后面有字符的情况。如果数字后面有字符,那么就是“CNCN”类型;否则就是“CN”类型。
bool CNCN = false; // char num char num
for (int i = 0; i + 1 < s.size(); i++)
if (s[i] >= '0' && s[i] <= '9' && s[i + 1] >= 'A' && s[i + 1] <= 'Z') // 存在数字后面是字符的情况
CNCN = true;
break;
那么,既然知道了输入是哪种类型,剩下的就是两种类型之间如何转换了。
在具体一点,就是“数字和字母”之间的转换。转换规则是:
数字 | 字符 |
---|---|
1 | A |
2 | B |
… | … |
26 | Z |
27 | AA |
28 | AB |
… | … |
52 | AZ |
53 | BA |
54 | BB |
数字转字符
数字转字符有点类似十进制转26进制。
但是不同的是,数字是从1开始的,也就是说数字0没有对应的字符。
如果是简单的进制转换,0应该对应字符A,但是这种情况下1对应字符A,因此在转换字符的每一位之前,把数字减去1即可。
string n2c(int n) // num to char
string ans;
while (--n >= 0)
ans = (char)(n % 26 + 'A') + ans;
n /= 26;
return ans;
终止条件n=0(0没有对应的字符),也就是 n − 1 < 0 n - 1 < 0 n−1<0时终止。
字符转数字
字符转数字其实就是数字转字符的逆过程。
B就对应2(‘B’ - ‘A’ + 1);BB就对应54((‘B’ - ‘A’ + 1) * 26 + (‘B’ - ‘A’ + 1))
因此从左到右遍历字符串的每一位,每次在之前的基础上乘以一个26,再加上此位对应的数字即可。
int c2n(string s)
int ans = 0;
for (int i = 0; i < s.size(); i++)
ans *= 26;
ans += s[i] - 'A' + 1;
return ans;
AC代码
#include <bits/stdc++.h>
using namespace std;
#define mem(a) memset(a, 0, sizeof(a))
#define dbg(x) cout << #x << " = " << x << endl
#define fi(i, l, r) for (int i = l; i < r; i++)
#define cd(a) scanf("%d", &a)
typedef long long ll;
/*
1 A
2 B
...
26 Z
27 AA
28 AB
...
52 AZ
53 BA
54 BB
*/
string n2c(int n) // num to char
string ans;
while (--n >= 0)
ans = (char)(n % 26 + 'A') + ans;
n /= 26;
return ans;
int c2n(string s)
int ans = 0;
for (int i = 0; i < s.size(); i++)
ans *= 26;
ans += s[i] - 'A' + 1;
return ans;
void debug_n2c() // Debug用,此函数可以不用管
for (int i = 1; i <= 1000; i++)
printf("%4d -> %s\\n", i, n2c(i).c_str());
exit(0);
void debug_c2n()
for (int i = 1; i <= 1000; i++)
printf("%d -> %s -> %d\\n", i, n2c(i).c_str(), c2n(n2c(i)));
exit(0);
int main()
int N;
cin >> N;
while (N--)
string s;
cin >> s;
bool CNCN = false; // char num char num
for (int i = 0; i + 1 < s.size(); i++)
if (s[i] >= '0' && s[i] <= '9' && s[i + 1] >= 'A' && s[i + 1] <= 'Z')
CNCN = true;
break;
string ans;
if (CNCN)
int row = 0;
int loc = 1;
for (loc = 1; s[loc] != 'C'; loc++) // 第一个数字部分
row *= 10;
row += s[loc] - '0';
ans = to_string(row); // 行
int col = 0;
for (loc++; loc < s.size(); loc++) // 第二个数字部分,计算出列
col *= 10;
col += s[loc] - '0';
ans = n2c(col) + ans;
else
int loc = 0;
while (s[loc] >= 'A' && s[loc] <= 'Z') // 字符部分
loc++;
ans += 'C';
ans += to_string(c2n(s.substr(0, loc))); // 将字符部分转为数字,再转为string类型
ans = s.substr(loc, s.size() - loc) + ans; // 行,本来就是数字
ans = 'R' + ans;
cout << ans << endl;
return 0;
点关注,不迷路
原创不易,转载请附上原文链接哦~
Tisfy:https://letmefly.blog.csdn.net/article/details/124512136
以上是关于码蹄集 - MT2051 · excel的烦恼的主要内容,如果未能解决你的问题,请参考以下文章