CodeForces - 1B Spreadsheets(进制转化)
在流行的电子表格系统 (例如 Excel) 中,使用以下的列编号方式。第一列编号为 A,第二列 — 编号为 B,等等,直到第 26 列被标识为 Z。然后使用两个字母的编号:第 27 列编号为 AA,第 28 列 — AB,第 52 列被标识为 AZ。在 ZZ 之后,接着使用三位字母进行编号,依次类推。
各行被标识为以 1 开头的整数。单元格的名称由列和行的编号组成。例如,BC23 是位于第 55 列、第 23 行的单元格名称。
有时使用另一种编号方式:RXCY,其中 X 和 Y 是整数,分别表示列和行的编号。例如,R23C55 表示前述示例中的单元格。
您的任务是写一个程序,读取给定的单元格坐标序列,并将每个单元格的编号方式转换为另一种编号方式。
输入
输入的第一行包含了整数 n (1 ≤ n ≤ 105),表示测试所用的坐标数目。然后跟随 n 行,每行均包含坐标。所有的坐标都是正确的,且列 和/或 行的数字不超过 106 。
输出
写出 n 行,每行应包含一个使用另一种编号方式的单元格坐标。
示例
输入
2 R23C55 BC23
输出
BC23 R23C55
看题目,一共两种形式表示,之间互相转化。个人感觉第一种形式(没有R C 的那个)好转化,直接将其中的字母转化为整型数据就可以了。但是第二种形式还要考虑整除和不整除。对于大佬来说,肯定很简单,对于我这个弱菜,有点难。
#include<iostream>
#include<stdio.h>
#include<bits/stdc++.h>
#include<string>
#include<sstream>
#include<string.h>
const int maxn=1005;
typedef long long ll;
using namespace std;
char s[maxn];
int b[maxn];
bool check()
{
if(s[0]=='R')
{
for(int i=1;i<strlen(s);i++)
{
if(!isalpha(s[i]))
continue;
if(s[i]=='C'&& !isalpha(s[i-1]) && !isalpha(s[i+1]))
return true;
}
}
return false;
}
int main()
{
int t;
cin>>t;
while(t--)
{
memset(b,0,sizeof(b));
bool flag=false;
cin>>s;
if(check())
{
string lie;
int lie1;
int hang1=0; //后面的那个数
sscanf(s,"R%dC%d",&hang1,&lie1);
int i=0;
while(lie1>0)
{
if(lie1%26==0)
{
b[i++]=26;
lie1--;
}
else
{
b[i++]=lie1%26;
}
lie1/=26;
}
i--;
for(;i>=0;i--)
printf("%c",b[i]+64);
cout<<hang1<<endl;
}
else
{
int lie=0;
int hang=0;
int i=0;
while(isalpha(s[i]))
{
lie=lie*26+(s[i]-'A'+1);
i++;
}
while(!isalpha(s[i])&&i<strlen(s))
{
hang=hang*10+(s[i]-'0');
i++;
}
cout<<'R'<<hang<<'C'<<lie<<endl;
}
}
return 0;
}
第二种形式的话,就是一位一位的算每一个字符,比如Z是26,'Z'-'A'+1, AZ 就是52,就是('A'-'A'+1)X 26+('Z'-'A'+1).然后你就找到规律了,isalpha( ),来判断是不是字母,就这样,然后就将其中的数字提取出来,就可以了。
while(isalpha(s[i]))
{
lie=lie*26+(s[i]-'A'+1);
i++;
}
下面看看第一种形式的处理,就像第二种转换为第一种的样子一样,像一个 结果=乘数X商+余数(可能是0),这个余数就是字母转化而来的,从这个余数,我们就可以得到原先的字母。下面我说说(可能是瞎说的,因为喝了冰阔落(可乐)),就像上面第二种转化为第一种的一样,比如5678 这个数据怎么来的,5X10X10X10+6X10X10+7X10+8X1,所以往回倒退的时候,是从后面逐渐往回退的,所以第一种转化为第二种的话,需要我们做取余和除法的操作,思路应该是这样。(感觉我在说小学数学)。这个不是十进制,而是26进制,比如Z 是26,下一个就是AA 是27....AZ是52,BA是53,所以说到整除时(26,52,78...),还没有进到下一位的(对于我菜鸡,有的坑,脑子转的慢,哎),这时操作是,( 拿52来说,取余为0 ( 最后一位是Z ) ,52/26=2( 是个字母 B ),这样算的话,是BZ,但是结果是AZ,就WA了。这时怎么办呢,只要遇见整除的,直接将这个被除数减一,毕竟大于等于26的数除以26都是大于0的,被除数减一,下一次的余数就会减一,就像52,商为2,减一,下次得到的字母就是A,这样就是正确答案了 AZ );不整除的话,跟十进制操作一样,取余和除法。 我们将这些余数( Z 整除例子)都保存在一个数组中(整形,在后面转化为字符 %c ),Z例子就是保存 26,其他数据保存余数。因为是取余数除法操作(是反着来的),所以我们输出字母都是倒着输出。就这样说完了。
接下来,就是交代码,看到Accept(绿色),内心一喜。
推荐阅读
-
CodeForces - 1B Spreadsheets 模拟
-
Codeforces 1B Spreadsheets
-
【题解】codeforces 1B Spreadsheets
-
CodeForces - 1B Spreadsheets(进制转化)
-
CodeForces - 1B Spreadsheets【模拟】
-
B - Spreadsheets CodeForces - 1B
-
【codeforces】1B Spreadsheets
-
【Codeforces 1B】Spreadsheets
-
codeforces 1B Spreadsheets
-
【题解】codeforces 1B Spreadsheets