Codeforces Beta Round #1 B. Spreadsheets 题解

题目链接:http://codeforces.com/contest/1/problem/B
题目大意:
《电子表格》
电子表格的第1列标记为A,第2列标记为B,……,第26列标记为Z。
然后我们用两个字符来进行:第27列标记为AA,第28列标记为AB,……,第52列标记为AZ。
……
在ZZ之后,我们再使用三个字符来表示。如是循环……
所以对于电子表格中的某一个元素,我们都可以按照上述方法标识它的列。
比如,对于第55列第23行的元素,我们可以用“BC23”来表示它。我们称这是“第一种表示”。

除了“第一种表示”外,还有“第二种表示”。
第二种表示的形式为“RXCY”,其中 X 和 Y 都是数字, X 表示行号, Y 表示列号。
比如,对于第55列第23行的元素,它的“第二种表示”为“R23C55”。

现在,给你 n 个字符串,对于每一个字符串,他可能是某一行某一列的“第一种表示”或“第二种表示”。
如果这个字符串是“第一种表示”,你需要将其转换为“第二种表示”;
否则,这个字符串就是“第二种表示”,你需要将其转换为“第一种表示”。
题目分析:
这个题目比较麻烦的地方在于它的进制转换上!
一位字符的范围在 [A, Z] 共 26 个数;
二位字符的范围在 [AA, ZZ] 共 26 x 26 个数;
三位字符的范围 [AAA, ZZZ] 共 26 x 26 x 26 个数;
以此类推, n 位字符的范围包含有 26^n 个数。
可以看出,对于具有固定位数 n 的字符对应的数,它其实就对应一个 n 位的26进制数。
所以,告知我们一个数 X ,我们确定它位数的方法为:
首先 n = 1;
比较 X 和 26 的大小,如果 X <= 26 ,返回 n; 否则,X -= 26 + 1, n = 2;(注意这里的 + 1 ,因为 Z + 1 才会变成 AA)
比较 X 和 26^2 的大小,如果 X <= 26*26,返回 n;否则,X-= 26*26 + 1, n = 3;
……
最终会:比较 X 和 26^n 的大小,找到 X <= 26^n,返回 n。
得到位数 n 以及此时的 X ,我们就可以根据剩下的 X 的值,来计算对应的字符了。
将数字转成字符表示的函数如下所示:

其次,我们考虑将一个字符串转成对应的数字,我们可以按照上述思想逆推回来进行思考:
对于一个长度为 n 的字符串 s ,它一定是经历了
26 (一位字符串)、
26^2 (二位字符串)、
26^3 (三位字符串)、
……
26^(n-1) (n-1位字符串)
的经历。
然后剩下的就是将这个 n 为字符串看做一个 26 进制数得到剩下的部分的数。实现代码函数如下:

最后整合一下上面两个代码。
另外一方面就是如何判断输入的字符串是“第一种表示”或“第二种表示”。不过这个不是问题,最难的问题已经在上面讲解完了。

这里需要特别注意的一点是,‘A‘并不代表0,而是代表1,所以在处理的时候,我们的转换逻辑是从0开始,但是处理逻辑却是从1开始,所以要处理好1这个数的差的细节。

实现代码如下:

#include <bits/stdc++.h>
using namespace std;

string change_d_to_s(int x) {
    x -= 1;
    int tmp_arr[10], n = 1, t = 26;
    while (x > t) {
        x -= t;
        t *= 26;
        n ++;
    }
    for (int i = 0; i < n; i ++) {
        tmp_arr[i] = x % 26;
        x /= 26;
    }
    string s = "";
    for (int i = n-1; i >= 0; i --) {
        char c = ‘A‘ + tmp_arr[i];
        s += c;
    }
    return s;
}

int change_s_to_d(string s) {
    int n = s.length();
    if (n == 1) {
        return s[0] - ‘A‘ + 1;
    }
    int t = 1, ans = 1;
    for (int i = 1; i < n; i ++) {
        t *= 26;
        ans += t;
    }
    t = 1;
    for (int i = n-1; i >= 0; i --) {
        int tmp = s[i] - ‘A‘;
        ans += tmp * t;
        t *= 26;
    }
    return ans;
}

int n, x, r;
string s;

int main() {
    cin >> n;
    while (n --) {
        cin >> s;
        if (s[0] == ‘R‘ && s[1] >= ‘0‘ && s[1] <= ‘9‘ && s.find(‘C‘) != string::npos) { // 第一种表示
            istringstream sstream(s);
            char ch_R, ch_C;
            sstream >> ch_R >> r >> ch_C >> x;
            cout << change_d_to_s(x) << r << endl;
        }
        else {  // 第二种表示
            int i;
            for (i = 0; s[i] >= ‘A‘ && s[i] <= ‘Z‘; i ++);
            istringstream sstream1(s.substr(0, i));
            string t;
            sstream1 >> t;
            istringstream sstream2(s.substr(i));
            sstream2 >> r;
            cout << "R" << r << "C" << change_s_to_d(t) << endl;
        }
    }
    return 0;
}

  

原文地址:https://www.cnblogs.com/mooncode/p/CF1B.html

时间: 2024-10-07 22:10:20

Codeforces Beta Round #1 B. Spreadsheets 题解的相关文章

Codeforces Beta Round #1 B. Spreadsheets

Codeblocks坏掉了,我不知道该怎么修,只能过两天重装系统了. 没办法.这个题是用Java写的,代码风格不好不要骂我~~ 题目大意: Excel表格那种坐标系统,和正常的坐标系统.用代码实现转换. 就是模拟题啊,代码量比较小. 下面是代码: import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner cin = new Scanner(System.in); i

Codeforces Beta Round #91 (Div. 1 Only) E. Lucky Array

E. Lucky Array Petya loves lucky numbers. Everybody knows that lucky numbers are positive integers whose decimal representation contains only the lucky digits 4 and 7. For example, numbers 47, 744, 4 are lucky and 5, 17, 467are not. Petya has an arra

Codeforces Beta Round #85 (Div. 1 Only) C (状态压缩或是数学?)

C. Petya and Spiders Little Petya loves training spiders. Petya has a board n × m in size. Each cell of the board initially has a spider sitting on it. After one second Petya chooses a certain action for each spider, and all of them humbly perform it

CodeForces Beta Round #1

Codeforces Beta Round #1 A. Theatre Square [题意]一个n*m的矩形广场,用a*a的方形石板铺设,问最少需要多少块石板能铺满广场. [思路]水题,从n方向来看能能够铺设ceil(n/a)块,从m方向来看能能够铺设ceil(m/a)块,总共有ceil(n/a)*ceil(m/a)块. 1 /* 2 ** CodeForces 1A Theatre Square 3 ** Created by Rayn @@ 2014/05/18 4 */ 5 #inclu

暴力/DP Codeforces Beta Round #22 (Div. 2 Only) B. Bargaining Table

题目传送门 1 /* 2 题意:求最大矩形(全0)的面积 3 暴力/dp:每对一个0查看它左下的最大矩形面积,更新ans 4 注意:是字符串,没用空格,好事多磨,WA了多少次才发现:( 5 详细解释:http://www.cnblogs.com/cszlg/p/3217478.html 6 */ 7 #include <cstdio> 8 #include <algorithm> 9 #include <cstring> 10 #include <cmath>

Codeforces Beta Round #6 (Div. 2 Only) B. President&#39;s Office

题目大意 给出一个n*m的矩阵 ,描述桌子的布局.总统的桌子和他的副手的桌子相邻,每一个人的桌子有它独有的颜色.问总统有多少个副手. 解题思路 搜出总统的桌子在矩阵中的边界后判断边界外的其它颜色桌子的数量. 题目代码 #include <set> #include <map> #include <queue> #include <math.h> #include <vector> #include <string> #include

图论/暴力 Codeforces Beta Round #94 (Div. 2 Only) B. Students and Shoelaces

题目传送门 1 /* 2 图论/暴力:这是个连通的问题,每一次把所有度数为1的砍掉,把连接的点再砍掉,总之很神奇,不懂:) 3 */ 4 #include <cstdio> 5 #include <cstring> 6 #include <algorithm> 7 #include <cmath> 8 using namespace std; 9 10 const int MAXN = 1e2 + 10; 11 const int INF = 0x3f3f3

Codeforces Beta Round #1 C. Ancient Berland Circus

果然Java还是不靠谱啊,一个NaN把我整了半天~~ 题目大意: 有一个正多边形,给出任意三个顶点的坐标,求这个正多边形的最小面积. 解题思路: 首先要知道这三个顶点组成的三角形的外接圆一定是这个正多边形的外接圆. 用过计算出三角形的三边长,可以计算出三角型面积,进而推出外接圆半径. 可以得到三个圆心角,找出最大公约数,那就是最大角度. 就可以计算出多边形面积了~~ 下面是代码: import java.text.DecimalFormat; import java.util.Scanner;

codeforces Beta Round #19 D. Point (线段树 + set)

题目大意: 对平面上的点进行操作. add x y 在 (x,y )上加一个点. remove x y 移除 (x,y)上的点. find x y 求出在(x,y)右上角离他最近的点,优先级是靠左,靠下. 思路分析: find 操作 比较麻烦. 要保证x大的同时还要确保x最小,而且该x上还要有点. 这样要找大的时候要小的,就是在线段树上选择性的进入左子树还是右子树. 所以核心就是,用set维护叶子节点. 然后查找的时候去叶子节点找,如果这个叶子节点有蛮子的 x y  就输出,否则回溯去另外一个子