要说这周最有意义的算法,就是截止到今天为止,今天花了一早上写出来的一道B类型的算法题。同时,写出来这道题也给我带来了许多感想,最先开始,我读完题,感觉可以写,又不知道怎么写,然后想了一阵,就去网上查查,很不幸,查到的都是c++版本,其实每次用java写算法我都希望找到一些java版本的思路,很可惜几乎每次都没有,看着c++的版本我有没心思去看,找了几篇全是c++版本的,然后就想着放弃了。但是毕竟想了有一个小时了,想想还是死磕吧,其实很多时候我想放弃的算法大多是看到题解代码很长后而想着放弃了,因为我总是感觉自己很难写出来这么长的代码。但这次,我通过一个上午的死磕还真的就写出来了这么长的代码,甚至怀疑不是我写的,同时又隐约的明白,很多时候哪些看似很长的代码,都是在一定的逻辑思路下,堆出来的,若你没那个思路,你就感觉那个代码很长,如果你掌握了思路,你就很清晰很明白每一块是在干啥。至于这道题对于我算法上所带来的感悟是,这相当于是一个二十六进制,要注意的是满二十六后,它对应Z同时还要把这个数除以二十六的结果再减一,因为相当于是借位了。对于字母转成数字就字母在本道题对应的数字*26的对应位次方,可能也跟我最近学了二进制的课程有关所以才有了这个思想吧。总的来说,现在心情是真的好,不枉费这一上午时间。下面就是这道题相关信息:
题目: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
代码:
import java.util.Scanner;
public class 电子表格 {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int t=sc.nextInt();
sc.nextLine();
for(int i=0;i<t;i++) {
String value="";
String s=sc.nextLine();
if(judge(s)==2&&s.charAt(1)<65) {
for(int j=s.length()-1;j>=0;j--) {
if(s.charAt(j)>='0'&&s.charAt(j)<='9') {
value=s.charAt(j)+value;
}else {
break;
}
}
String res=oneToTwo(value);
value="";
for(int j=1;j<s.length();j++) {
if(s.charAt(j)>='0'&&s.charAt(j)<='9') {
value=value+s.charAt(j);
}else {
break;
}
}
System.out.println(res+value);
}else {
String num="";
for(int j=0;j<s.length();j++) {
if(s.charAt(j)>=65&&s.charAt(j)<=90) {
num=num+s.charAt(j);
}else {
break;
}
}
String res=twoToOne(num);
num="";
for(int j=s.length()-1;j>=0;j--) {
if(s.charAt(j)>='0'&&s.charAt(j)<='9') {
num=s.charAt(j)+num;
}else {
break;
}
}
System.out.println('R'+num+'C'+res);
}
}
sc.close();
}
public static String oneToTwo(String s) {
int real=Integer.valueOf(s);
String res="";
while(real>26) {
if(real%26!=0) {
res=(char)(real%26+64)+res;
real/=26;
}else {
res='Z'+res;
real=real/26-1;
}
}
if(real==26) {
res='Z'+res;
}else {
res=(char)(real%26+64)+res;
}
return res;
}
public static String twoToOne(String s) {
int num=0;
for(int i=s.length()-1,j=0;i>=0;i--,j++) {
num+=(s.charAt(i)-64)*(int)(Math.pow(26, j));
}
String res=String.valueOf(num);
return res;
}
public static int judge(String s) {
int num=0;
for(int i=0;i<s.length();i++) {
if(s.charAt(i)>=65&&s.charAt(i)<=90) {
num++;
}
}
return num;
}
}
反正乍一看代码是真的长,可能这是我目前为止在算法上自己写出来的最长的代码了吧哈哈。真正要是明白了,其实也就那么点东西,两种转换方式的方法,还有一个判断的方法,其他也没啥东西。
然后就是眼瞅着蓝桥杯就快要来了,而自己还是没能自己写几道关于树和图的算法,几个月前还想拿省一的想法渐渐褪去,现在感觉应该稳拿省二,但对省一还抱有那么一丝幻想,除了明天的小组赛可能顶多就2个晚上的学算法的时间了。等蓝桥杯一过可能就不再学算法了,死学两个月英语一把过六级,然后就开始早早的准备考研了,要想有十足的把握上岸,我觉得应该越早准备越好,这不仅给我的是实力同时也是很难抹灭的信心。很难想象这是我倒数第几次在csdn写博客了。