第二场(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;
}
};
查看9道真题和解析