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


  • 相关阅读:
    vue项目中使用定时器,离开页面时清除定时器
    不能在循环中使用res.send(err);
    React使用require加载图片失败
    实验五 单元测试
    实验四 代码评审
    UML 建模工具的安装与使用
    结对编程 第二阶段
    结对编程
    GIT 代码版本管理
    结构化方法与面向对象化方法的比较
  • 原文地址:https://www.cnblogs.com/AWCXV/p/7632428.html
Copyright © 2020-2023  润新知