Time Limit: 3 second
Memory Limit: 2 MB
【问题描述】
编码工作常被运用于加密文件或压缩传输。这里我们用一种最简单的编码方式进行编码:把一些有规律的单词编成数字。字母表中共有26个字母{a,b,c,…,z},这些特殊的单词长度不超过6且字母按升序排列。把所有这样的单词放在一起,按字典顺序排列,一个单词的编码就对应着它在字典中的位置。
例如:
a→1
b→2
z→26
ab→27
ac→28
abc→352
abd→353
【输入】
仅一行,被编码的单词
【输出】
仅一行,对应的编码。如果单词不在字母表中,输出0。
【输入样例】
ab
【输出样例】
27
【题解】
解释一下样例。
a是1 z 是26,
到了z,没有任何元素可以加了。就让这个字符串变成2位。
我们先变成a,然后要满足从小到大,且字母前一个小于后一个。则变成“ab”
所以ab就是27.
以此规律 我们可以用一个字符串s2,s2一开始=="a",然后我们不断给他最后一位递增.直到为z。
到了z,我们先判断一下是否要增加位数。
这个问题我们用x,y,z来讲。假设我们的3位数变成xyz了,即最后一位是z,且前面的数递减。这个时候我们就会发现没有字母可以递增了。也就是说这个时候要增加string的长度了。则我们随便添加上一个字幕+=“x”;然后从第0到l-1位(string是从0开始的),依次赋值为a,b,c,d。。。。;然后再进行递增。
还有一种情况,就是不用增加位数。
比如tuwxyz;
这里我们先从后往前找到第一个 i 使得a[i] != (a[i+1]-1),即u,然后我们让U递增就好。
每次操作的时候将操作数递增即可。
错误会有出现不是小写字母的情况,还有不是顺序的情况。要注意。
【代码】
#include <cstdio>
#include <string>
#include <iostream>
#include <stdlib.h>
using namespace std;
string s1;
int now = 1;
void input_data()
{
cin >> s1;
int ll = s1.size();
ll--;
for (int i = 0;i <= ll-1;i++) //这里是判断错误的情况 直接输出0结束程序
{
if (s1[i] > s1[i+1])
{
printf("0");
exit(0);
}
if ( s1[i] <'a' || s1[i] > 'z')
{
printf("0");
exit(0);
}
}
}
void get_ans()
{
string s2 = "a"; //初始化 s2,将s2递增,直到s2 == s1为止
while ( s2 != s1) //每次操作都要递增操作数now
{
int l = s2.size();
l--;
if (s2[l] < 'z') //判断最后一位的情况 如果小于z就可以直接递增
{
s2[l]++;
now++;
}
else //如果等于z
{
bool bo = true; //这里判断是否要增加位数 bo最后如果为true则增加位数
for (int i = l-1;i >= 0;i--)
if (s2[i] != (s2[i+1] - 1))
{
bo = false;
break;
}
if (bo) //增加位数
{
l++;
s2+="a";//随便增加
for (int i = 0;i < =l;i++)//最后重新复制成a->a+l-1
s2[i] = 'a' + i;
now++;
}
else //不用增加位数,就从后往前找到一个位置,即可以递增的位置。
{
int temp = l-1;
while (s2[temp] == s2[temp+1]-1) //这是不能递增的情况,即严格的从z->y->x。。。这样不能递增
temp--;
s2[temp]++;
for (int i = temp+1;i <= l;i++)
s2[i] = s2[i-1] + 1;
now++;
}
}
}
}
void output_ans()
{
printf("%d",now); //最后输出操作数
}
int main()
{
input_data();
get_ans();
output_ans();
return 0;
}