📂题解
🔖数学
2023-03-01 16:05阅读: 18评论: 0推荐: 0

CF1B-Spreadsheet题解

题目传送门

题意:在表格中格子有两种表示方式,一种为列从 A-Z,AA-ZZ,AAA-ZZZ...,行为 1,2,3...,如 B2BC23 等。另一种为 R+行+C+列 的形式,如 R23C45 等。你需要进行回答若干次询问,每次给出一个坐标,将其转换为另一种形式。

首先需要判断输入的是哪种形式,两种较为简洁的做法如下:

  1. 可以使用 sscanf 或 stringstream 来从字符串进行读入,判断是否能读入到 char+int+char+int 类型。
  2. 可以将字母和数字分段存入 vector,判断有几段。

处理主要涉及 10 进制和 26 进制的互相转换,这一步基本没有太大区别,可以循环也可以递归。

做法一 By ZhouYuChen

#include<cstdio>
void g(int t){if(t){g((t-1)/26);putchar(65+(t-1)%26);}}
int main(){
	int n,x,y;
	char s[64],*p;
	for(scanf("%d ",&n);n--;){
		gets(s);
		if(sscanf(s,"%*c%d%*c%d",&x,&y)==2){
			g(y);
			printf("%d\n",x);
		}else{
			for(x=0,p=s;*p>64;++p)
				x=x*26+*p-64;
			printf("R%sC%d\n",p,x);
		}
	}
	return 0;
}

做法二 By RAD

char buf[110000];

inline int from(string &s) {
    int res = 0;
    forn(i, s.size())
        res = res * 26 + s[i] - 'A' + 1;

    return res;
}

inline void toRC(vector<string> &v) {
    printf("R%dC%d\n", atoi(v[1].c_str()), from(v[0]));
}

void to(int x) {
    int st = 1, len, sum = 0;
    forn(i, 20) {
        st *= 26;
        sum += st;
        if (x <= sum) {
            len = i + 1;
            break;
        }
    }

    x -= sum - st + 1;
    string res(len, 'A');
    forn(i, len) {
        res[len - i - 1] += x % 26;
        x /= 26;
    }

    printf("%s", res.c_str());
}

inline void fromRC(vector<string> &v) {
    to(atoi(v[3].c_str()));
    printf("%s\n", v[1].c_str());
}

int main() {
    int tt;
    scanf("%d", &tt);
    forn(ii, tt) {
        scanf("%s", buf);
        string s = buf;

        vector<string> v;
        forn(i, s.size()) {
            int j = i;
            string cur;
            while (j < (int)s.size() && isalpha(s[j]) == isalpha(s[i])) {
                cur += s[j];
                j++;
            }

            i = j - 1;
            v.pb(cur);
        }

        if ((int)v.size() == 2)
            toRC(v);
        else
            fromRC(v);
    }

    return 0;
}
posted @   曹轩鸣  阅读(18)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起