原题:
/*
描述
为了最大程度地节约存储空间,经常需要把信息进行编码。一种很有效的编码方法是用数字来表示一串字符。假设这些字符串都是由不重复的英文小写字母组成的,且每个字符串中的英文字母都是从小到大排列的。
这个编码系统按照如下的方式工作:
字符串是按照长度从小到大的顺序排列的
长度相同的字符串,是按照字典需排列的
则根据这个编码系统,所有的字符串从 a 开始可以编码如下:
a - 1 b - 2 … z - 26 ab - 27 … az - 51 bc - 52 … vwxyz - 83681 …
那么,请编程计算出一个字符串在这个编码系统下编码后的值是多少。
输入
输入的第一行为 N,表示有 N 组数据。后面的 N 行每行包含一个不超过 10 个字母的字符串。
输出
输出字符串所对应的编码,如果该字符串不能被编码,则输出 0。
测试用例 1 以文本方式显示
1
bf
以文本方式显示
55
*/
解决代码:
#include<stdio.h>
#include<string.h>
#include <iostream>
#include <math.h>
using namespace std;
long long t[10][26]= {0}; //查表,将最简形式的编码事先准备好
/*
行号: 0 1 2 3 4 ... 24 25
列号:0 a b c d e ... y z
1 ab bc cd de ef ... yz zz
2 abc bcd cde efg ghi ... xyz zzz
3
4
...
9 abcdefghij ..... qrstuvwxyz ...zzzzz
*/
void init_table()
{
int i,j;
for(i=0;i<26;i++)
{
t[0][i]=i+1; //对应的是 a/b/c/.../z的编码是1-26;
}
for(i=1;i<10;i++)
{
t[i][0]=t[i-1][25]+1; //abc 总是等于上一行(降阶) yz +1
for(j=1;j<26-i;j++)
{
t[i][j] = t[i][j-1] + 1 + t[i-1][25] - t[i-1][j];
//cde - bcd = byz + 1 - bcd = 1 + yz - cd
}
for(j=26-i;j<26;j++)
{
t[i][j]=t[i][j-1]; //因为z2、y3这些不合法,所以无增加编码,都是和前面的最简式子一样的数
}
}
return;
}
long long lookup(char *sNum)
{
/*
举例:
bdfxz = b4 - c3 + d3 - e2 + f2 - g1 +x1 - y0 +z0
*/
long long ret =0;
int i,j;
char *p = sNum;
int n = strlen(p);
while(n>1)
{
i = n-1;
j = *p - 'a';
ret = (t[i][j] - t[i-1][j+1]) + ret;
n--;
p++;
}
ret += t[0][*p-'a'];
return ret;
}
int main(void)
{
int i,j,k;
char s1[80]="vwxyz";
//Soloe@csdn 欢迎转载,但请保留
init_table();
int n;
cin>>n;
while(n>0)
{
cin>>s1;
cout<<lookup(s1)<<endl;
}
return 0;
//Soloe@csdn 欢迎转载,但请保留
}