码蹄集 - 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(1T105)表示将有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;
    

那么,既然知道了输入是哪种类型,剩下的就是两种类型之间如何转换了。

在具体一点,就是“数字和字母”之间的转换。转换规则是:

数字字符
1A
2B
26Z
27AA
28AB
52AZ
53BA
54BB

数字转字符

数字转字符有点类似十进制转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 n1<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的烦恼的主要内容,如果未能解决你的问题,请参考以下文章

码蹄集 - MT3111· 赋值

算法竞赛入门码蹄集新手村600题(MT1201-1250)

算法竞赛入门码蹄集新手村600题(MT1501-1550)

算法竞赛入门码蹄集新手村600题(MT1551-1600)

算法竞赛入门码蹄集新手村600题(MT1401-1450)

算法竞赛入门码蹄集进阶塔335题(MT2326-2330)