CodeForces 1B Spreadsheets
题目(链接):
Spreadsheets
Time Limit:10000MS Memory Limit:65536KB
- Description
在一些知名的表格处理系统中(比如:excel表格),我们经常用大写的字母来表示列,例如A表示第1列,B表示第2列,第26列用Z来表示,同时第27列我们用AA来表示,第28列我们用AB来表示,第29列我们用AC来表示,AZ表示第52列,ZZ之后我们就需要用3个字母来表示列了。
行的表示比较简单,我们一般用正整数来表示,比如1就表示第1行,5就表示第5行,行和列一起表示成为类似BC23的情况,这个表示在第23行,第55列。
有时候,我们的系统也会用RXCY的格式来表示,X和Y是整数,分别表示行号和列号。例如:R23C55表示的位置和之前那个例子是一样的。
你的任务是写一个程序,将这些位置在两种不同的表示方法之间转化。
- Input
第一行是一个正整数n(1<=n<=10^5), 表示测试数据的数量。
接下来n行,每行一串字符,表示一个位置,输入保证所有的位置都是正确的,没有一个位置的行号或者列号超过10^ 6。
- Output
输出n行,每行是对应的位置的转化结果。
Sample Input
2
R23C55
BC23
Sample Output
BC23
R23C55
评析
本题是一条简单的模拟,主要算法在于十进制和二十六进制的转换,但是题目中所要求的并不是标准的二十六进制,要注意在边界情况的进位,另外本题使用了字符数组代码显得冗长,适当采用STL可以使代码更简洁美观。
代码示例
#include <cstring>
#include <cstdio>
#include <cstdlib>
using namespace std;
char save[100005];
char ans[10];
bool kind(char a[], int len)
{
if(a[0]=='R'&& a[1] < 60 && len >=4)
{
for(int i=2;i<len;++i)
{
if(a[i]=='C')
return true;
}
}
return false;
}
int qp(int n,int k)
{
if(!k)return 1;
int tmp=qp(n,k/2);
if(k&1) return (tmp*tmp)*n;
return tmp*tmp;
}
char* trans1(int ori)
{
int i = 0;
int tmp[10];
memset(ans,0,10);
memset(tmp,0,10);
while(ori )
{
ans[i] = 64 + ori%26;
if(ans[i]== 64)
ans[i] = 90;
if(ans[i] == 90)
ori--;
ori /= 26;
i++;
}
for(int j=0;j<i;j++)
{
tmp[j] = ans[j];
}
for(int j=0;j<i;j++)
{
ans[j]=tmp[i-1-j];
}
return ans;
}
int trans2(char a[])
{
int len = strlen(a);
int ans = 0;
for(int i=0;i<len;i++)
{
ans += (a[i]-64)*qp(26,len-1-i);
}
return ans;
}
int main()
{
int T;
scanf("%d",&T);
char a[20];
int r,c,cnt;
while(T--)
{
scanf("%s", a);
int len = strlen(a);
if(kind(a, len))
{
int i=1;
while(a[i] != 'C')
{
save[i-1] = a[i];
i++;
}
cnt = i;
save[i-1] = '\0';
r = atoi(save);
i++;
while(a[i] != '\0')
{
save[i-1-cnt] = a[i];
i++;
}
save[i-1-cnt]='\0';
c = atoi(save);
printf("%s%d\n",trans1(c),r);
}
else
{
int i = 0;
while(a[i] > 60)
{
save[i] = a[i];
i++;
}
cnt =i;
save[i] = '\0';
c = trans2(save);
while(a[i] != '\0')
{
save[i-cnt] = a[i];
i++;
}
save[i-cnt]='\0';
r = atoi(save);
printf("R%dC%d\n",r,c);
}
}
}