CodeForces #1 B. Spreadsheets


传送门:

http://codeforces.com/contest/1/problem/B

类型:

简单模拟,进制转换

题意:

对于第23行第55列,有两种描述方式:

一种是R23C55

一种是BC23。其中BC表示55.(A->1,Z->26,AZ->27)

给出其中一种表达方式,求另一种

思路:

本题就是10进制和以1开始的 1-26 这特殊的 26进制 的相互转换。

方法:

10 to 1-26

while (c) {
    re[p--] = (c-1)%26 + 'A';
    c = (c-1)/26;
}

从低位到高位的顺序输出。

注意 c-1,每次相当与把个位的 1-26 转换成了 0-25 这正常的26进制,然后后面的除法相当于把这位砍掉。

 

1-26 to 10

while (p < len) {
    c += cc[p++] - 'A' + 1;
    c *= 26;
}

从高位到低位读入

代码:

/*************************************************************************
    > File Name:    cf1_b.cpp
    > Author:       Shine
    > Created Time: 2013-05-30 上午 12:54:29
    > QuestionType: 进制转换
    > Way: 取末尾数,然后转换为相应的数
    > Submit: 1WA(没考虑好 从1开始的 进制处理) 1AC
    > Gain: 进制取从末尾一个一个取出,放从末尾一个一个放入。从1开始 要注意转换
    > Experience: 多测试一些数据。
 ************************************************************************/
#include <cstdio>
#include <cstring>
#define N 1000100

void AtoB(char str[]) {
    char re[N];
    int p = N-1;
    int r, c;
    sscanf(str, "R%dC%d", &r, &c);

    re[p--] = 0;
    while (r) {
        re[p--] = r%10+'0';
        r /= 10;
    }
    while (c) {
        re[p--] = (c-1)%26 + 'A';
        c = (c-1)/26;
    }
    printf("%s\n", &re[p+1]);
}

void BtoA(char str[]) {
    char cc[N];
    int c = 0;
    int r;
    sscanf(str, "%[A-Z]%d", cc, &r);
    int len = strlen(cc);
    int p = 0;
    while (p < len) {
        c += cc[p++] - 'A' + 1;
        c *= 26;
    }
    c /= 26;
    printf("R%dC%d\n", r, c);
}


int main() {
    char str[N];
    int r; int c;
    int t;
    scanf("%d", &t);
    while (t--) {
        scanf("%s", str);
        int a, b;
        if (sscanf(str, "R%dC%d", &a, &b) == 2)  AtoB(str);
        else BtoA(str);
    }
    return 0;
}
CodeForces #1 B. Spreadsheets
原文地址:https://www.cnblogs.com/shinecheng/p/3107352.html