第二场(B2-破译密码)

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

题目描述:
牛牛收到了一个任务,任务要求牛牛破译一个密码。牛牛将被给予两个字符串s1和s2,均由四个小写字母构成。需要破译的密码为从s1变换到s2最少需要的变换次数。
变换的方式是这样:每次变换可以选择当前字符串中的一个位置,然后剩下的三个位置的字符从左到右分别加上2,3,5,若是超出'z',则重新从'a'开始,例如:对于字符串"abcd",我们选择'c'的位置进行变换,则变换之后的字符串为"ceci";对于字符串"qyzr",我们选择'r'位置进行变换,则变换之后的字符串为"sber"。

输入
"aaaa","ccgk"
输出
2
说明:第一次变换选择第一个'a',变成"acdf",第二次变换选择第二个'c',变成"ccgk",故答案为2
备注:
s1,s2均由四个小写字母组成
解题思路:
“最少变换次数”,可以使用bfs。常规的广搜套路,根据当前结点变换得到下一结点,同时利用集合判断是否访问过,如果未访问就入队。
代码:

#include <bits/stdc++.h>
class Solution {
public:
    /**
     * 返回最终的答案
     * @param s1 string字符串 表示初始的字符串
     * @param s2 string字符串 表示目标的字符串
     * @return int整型
     */
    int solve(string s1, string s2) {
        // write code here
        if(s1 == s2) return 0;
        int cnt = 0;
        queue<string> q;
        unordered_set<string> st;
        q.push(s1);
        st.insert(s1);
        while(!q.empty()) {
            int sz = q.size();
            while(sz--) {
                string t = q.front();
                if(t == s2) return cnt;
                q.pop();
                for(int i = 0; i < 4; ++i) {
                    string s = fun(t, i);
                    if(!st.count(s)) q.push(s), st.insert(s);
                }
            }
            ++cnt;
        }
        return -1;
    }

    string fun(string s, int x) {
        int j = 0;
        int add[] = {2, 3, 5};
        for(int i = 0; i < 4; ++i) {
            if(i != x) {
                s[i] = 'a' + (s[i] - 'a' + add[j]) % 26;
                ++j;
            }
        }
        return s;
    }
};
全部评论

相关推荐

10-27 17:26
东北大学 Java
点赞 评论 收藏
分享
努力学习的小绵羊:我反倒觉得这种挺好的,给不到我想要的就别浪费大家时间了
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务