牛客编程巅峰赛S1第8场 - 黄金&钻石 B.字符串模拟C.bfs

链接:https://ac.nowcoder.com/acm/contest/6777/B
来源:牛客网

题目描述
牛牛想给牛妹写信,但是牛牛怕信中的信息泄露出去,于是用playfair加密信息。加密过程中的j都由i来代替。playfair加密算法首先需要绘制密码表,密码表是一个5*5的矩阵,开始由密钥按顺序排列,其余按照未出现的字母顺序。若密钥中含有重复字母需要将重复字母去掉,若有j用i来代替,例如密钥为nowcoder,得到的密码表为

加密明文需要符合以下规则:
将明文中每两个字母组成一对,若成对后是两个相同字母或留下一个字母无法成对,则不进行变化直接放入密文中
明文对p1p2在同一行,对应密文对c1c2分别为紧靠p1p2右端的字母,最后一列右端对应第一列。例如明文对为rf,对应密文对为ae
明文对p1p2在同一列,对应密文对c1c2分别为紧靠p1p2下方的字母,最后一行下方对应第一行。例如明文对为rv,对应密文对为ho
明文对p1p2不在同一行且不在同一列,对应密文对c1c2分别为p1p2确定的矩形中的同行另外两角,例如明文对为hb,对应密文对为kr
现在牛牛告诉你密钥和明文你能告诉牛牛密文是什么吗?

示例1
输入
复制
“nowcoder”,“iloveyou”
输出
复制
“kgrobunv”
备注:
1\leq|key|\leq 261≤∣key∣≤26,1\leq |str|\leq 10^31≤∣str∣≤10
3
,输入保证都为小写字母

class Solution {
public:
    char mib[5][5] = { 0 };//加密表
    int pc[300] = { 0 };//桶去重
    string zmb = "abcdefghijklmnopqrstuvwxyz";//预处理字母表
    string Encode(string key, string str) {
        string zzw;
        for (int i = 0; i < key.length(); i++)//桶去重 并形成加密表的串
        {
            if (pc[key[i]] == 0) {
 
                if (key[i] == 'j' || key[i] == 'i')//替换j和i
                {
                    pc['j'] = 1;
                    pc['i'] = 1;
                    zzw += 'i';
                }
                else
                {
                    zzw += key[i];
                    pc[key[i]] = 1;
                }
            }
 
        }
        for (int i = 0; i < zmb.length(); i++)//桶去重 并形成加密表的串
        {
            if (pc[zmb[i]] == 0) {
                if (zmb[i] == 'j')//j不要 也不替换i一定会出现一次
                {
                    continue;
                }
                else
                {
                    zzw += zmb[i];
                    pc[zmb[i]] = 1;
                }
            }
        }
        int k = 0, mp = 0;
        for (int i = 0; i < 5; i++)
        {
            for (int j = 0; j < 5; j++)//预处理加密表
            {
                mib[i][j] = zzw[k++];
            }
        }
        for (int i = 0; i < str.length(); i++)//原文j替换为j
        {
            if (str[i] == 'j')str[i] = 'i';
        }
        string mw;
        for (int i = 0; i < str.length() - str.length() % 2; i += 2)//让i只会到偶数停下 奇数的话 下面有处理
        {
            int zbx = 0, zby = 0, zbx1 = 0, zby1 = 0;
            for (int iq = 0; iq < 5; iq++)//查找加密表坐标
            {
                for (int jq = 0; jq < 5; jq++)
                {
                    if (mib[iq][jq] == str[i])
                    {
                        zbx = iq;
                        zby = jq;
                    }
                }
            }
            for (int iq = 0; iq < 5; iq++)//查找加密表坐标
            {
                for (int jq = 0; jq < 5; jq++)
                {
                    if (mib[iq][jq] == str[i + 1])
                    {
                        zbx1 = iq,
                            zby1 = jq;
                    }
                }
            }
            if (str[i] == str[i + 1])
            {
                mw += str[i];
                mw += str[i + 1];
            }
            else if (zbx == zbx1 && zby != zby1)
            {
                mw += mib[zbx][(zby + 1) % 5];
                mw += mib[zbx1][(zby1 + 1) % 5];
            }
            else if (zbx != zbx1 && zby == zby1)
            {
                mw += mib[(zbx + 1) % 5][zby];
                mw += mib[(zbx1 + 1) % 5][zby1];
 
            }
            else if (zbx != zbx1 && zby != zby1)
            {
                mw += mib[zbx][zby1];
 
                mw += mib[zbx1][zby];
            }
        }
        if (str.length() % 2 == 1)//处理多一个字母的情况
        {
            mw += str[str.length() - 1];
        }
        return mw;
    }
};

链接:https://ac.nowcoder.com/acm/contest/6777/C
来源:牛客网

题目描述
牛牛非常擅长摇骰子,不管给他一个什么样的骰子他都能准确的掷出他想要的那一面。现在有一个四面体骰子,四个面分别是四个整数0,3,7,11。牛牛在玩一个游戏。牛牛初始在一个数轴的原点,每当他摇出一个数字x,他可以自行选择向左走x步或者向右走x步。牛牛想知道他最少摇多少次骰子可以从原点到达坐标为p的点。
现在一共有N次询问,请你返回从0点到询问的每一个坐标arr[i]所需要摇筛子的最小次数。

示例1
输入
复制
[1,4,14]
输出
复制
[3,2,2]
说明
从0到1最少需要摇3次骰子(0->7->4->1)(走法不唯一,比如0->11->4->1也只需要掷3次骰子)
从0到4最少需要摇2次骰子(0->7->4)
从0到14最少需要摇2次骰子(0->7->14)
示例2
输入
复制
[6,25]
输出
复制
[2,3]
说明
从0到6最少需要摇2次骰子(0->3->6)
从0到25最少需要摇3次骰子(0->7->18->25)
备注:
对于20%的数据1\leq N\leq 5,1\leq arr[i]\leq 1e51≤N≤5,1≤arr[i]≤1e5

对于50%的数据1\leq N\leq 1e5,1\leq arr[i]\leq 5e51≤N≤1e5,1≤arr[i]≤5e5

对于100%的数据1\leq N\leq 1e5,1\leq arr[i]\leq 1e91≤N≤1e5,1≤arr[i]≤1e9

class Solution {
public:
    /**
     * 把所有询问的答案按询问顺序放入vector里
     * @param arr int整型vector 要查询坐标的数组
     * @return int整型vector
     */
    int v[1005];
    int a[5]={0,3,7,11};
    typedef long long ll;
    typedef pair<ll,ll>pll;
    vector<int> MinimumTimes(vector<int>& arr) {
        // write code here
        queue<pll>q;
        q.push(pll(0,0));
        v[0]=0;
        while(!q.empty()){
            pll no=q.front();
            q.pop();
            for(int i=0;i<4;i++){
                for(int j=-1;j<2;j+=2){
                    int x=no.first+a[i]*j;
                    if(x>=1&&x<=1000){
                        if(!v[x]){
                            v[x]=no.second+1;
                            q.push({x,v[x]});
                        }
                    }
                }
            }
            
        }
        vector<int>res;
        for(auto i:arr){
            if(i>22){
                res.push_back((i-11)/11+v[i%11+11]);
            }
            else res.push_back(v[i]);
        }
        return res;
    }
};

你可能感兴趣的:(牛客)