【4003】编码

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;
}


原文地址:https://www.cnblogs.com/AWCXV/p/7632428.html