来自Vic_:http://blog.csdn.net/Vic___
每周一道算法题安慰自己竞赛的心,囧
1B一个月前做的,当时专牛角尖,一个月后,昨天看组成原理,讲到进制转换的时候想起这道题了,突然灵光一闪,做出来了
原题地址:http://codeforces.com/problemset/problem/1/B
问题描述
题目理解
学点英语
spreadsheets n. 电子表格;电子数据表;试算表;空白表格程序
numeration n. 计算;数字的读法;[数] 命数法;编号
sequence
n. [数][计] 序列;顺序;续发事件
coordinates n. [数] 坐标;相配之衣物
coordinates n. [数] 坐标;相配之衣物
我的理解
这题是一个格式转换题目
在电子表格中,坐标一行是用字母来表示,一列是用数字表示的,这样好表示每一个单元格
那上图中的A1 另一种表示就是R1C1
R :row
C :column
说白了就是字母转换成数字或者数字转换成字母
字母转换数字
通过上图分析,显而易见,字母转数字,
第n字母就是26的n-1权重
,通过权重展开即可求得数字
数字转字母
上图可见,这其实26进制的转换,所以可以反复除26求余得到字母。
余数为0,我的处理方法是:
当余数为0,自动转换成Z,商减一
验证:702/26 商27……余0,0转换为Z,27-1=26;结果为ZZ。成立
解题代码
#include <stdio.h>
#include <stdlib.h>
const char Change[] ="ZABCDEFGHIJKLMNOPQRSTUVWXY";//字母 与 数字 转换
void main (){
int n;
scanf("%d",&n);
while(n--)
{
char a[100] ;
scanf("%s",a);
int flag=0;
int locc=2;
if(a[0]=='R'&&a[1]>='0'&&a[1]<='9')
{
while(a[locc]!='\0')//find C
{
if(a[locc]!='C'){
locc++;
}
else{
flag=1;
break;
}
}
}
if(flag)
{
char b[100],c[100];
int b_l=0,c_l=0;
int i;
for(i =1 ; i < locc;i++)
{
c[c_l++]=a[i];
}
c[c_l]='\0';
for(i = locc + 1 ; a[i]!='\0' ;i++)
{
b[b_l++]=a[i];
}
b[b_l]='\0';
long temp = atoi(b);
b[0] = '\0';
b_l=0;
while(temp>26)
{
if(temp%26==0)
{
b[b_l++]=Change[0]; //特殊处理
temp=temp/26 - 1;
}
else{
b[b_l++]=Change[temp%26];
temp=temp/26;
}
}
b[b_l++]=Change[temp%26];
b[b_l]='\0';
for(i = 0 ; i < b_l / 2 ; i ++)
{
char te;
te= b[i];
b[i]=b[b_l-i-1];
b[b_l-i-1]=te;
}
printf("%s%s\n",b,c);
}
else
{
char b[100],c[100];
int b_l=0,c_l=0;
int i ;
for(i = 0 ; a[i] !='\0';i++)
{
if(a[i]<'0'||a[i]>'9')
{
b[b_l++] =a[i];
}
else
{
c[c_l++] =a[i];
}
}
b[b_l]='\0';
c[c_l]='\0';
long result= 0;
long temp = 1 ;
for (i = b_l-1;i >= 0; i --)
{
result = result + ((b[i] - 'A') + 1)*temp;
temp = temp *26;
}
printf("R%sC%d\n",c,result);
}
}
}
代码解释
超时
因为个人习惯,喜欢使用C++和STL,第一遍,果断超时了
所以马上改成C语言,因为cin,cout重载慢耗不起时间
余数为0没有处理
刚开始,没有注意到余数问题,是注意到了26其实没有进位,27才进位,结果改成27,然后一下级权重的时候,进位又变了,发现太坑了,肯定不对。
重新整理思路,发现0是没有字母表示的,之前的算法Z一直是空着的,所以,明白了余数出现0肯定对应Z,然后商减一,结果对了
输入出错
因为之前懒,R出现后判断一下位是否是数字就确定是哪个型了,果然偷懒是没有好处。