目录
题目描述
输入描述
输出描述
用例
题目解析
算法源码
题目描述
无
输入描述
输入一个字符串,都是以大写字母组成,每个相邻的距离是 1,
第二行输入一个字符串,表示必过的点。
说明每个点可过多次。
输出描述
经过这些必过点的最小距离是多少
用例
输入 | ANTSEDXQOKPUVGIFWHJLYMCRZB |
输出 | 28 |
说明 | 无 |
题目解析
感觉本题题目描述太简略了,缺少很多关键信息。
- 第一行输入的字符串中是否有重复字母?
- 第二行输入的字符串中是否有重复字母?
- 运动起点在哪?一定是第一行第一个字母吗?(给出的用例无法解答该问题)
- 运动方向变更逻辑是啥?随意变更,还是必须到达终点后折返?(给出的用例无法解答该问题)
- 每个点可过多次,那么是否可以原地走?
因为题目没有这些关键信息,因此这道题目的难度就不确定了。
我是这样考虑的:
- 第一行和第二行都可能出现重复字母
- 运动起点必须从第一行输入的第一个字母开始
- 运动方向可以随意变更
- 允许原地走
这样的话,经过必过点的路径才能多样化,才有最小距离概念。
解题思路如下,首先统计第二行输入的必过点在第一行字符串中的索引位置,需要注意的是必过点可能在第一行中出现多次,我们都要统计到。
下面算法中,我们用points保存必过点信息,idxs保存必过点的索引信息。
接下来,通过dfs求解经过必过点的所有的可能路径。
之后计算这些路径的距离,即相邻两点求差绝对值,然后相加,需要注意的时,我们需要将从起点走到第一个必过点的距离也加入为路径距离。
然后,对所有路径距离进行排序,最小的就是题解。
自测用例:
ANTSEDXQOKPUVGIFWHJLYMCRZB
GUYA
最小距离44
ANTSEDXQOKPUVGIFWHUJLYMCRZ
GUYA
发现有两条路径
绿色路径更短,最小距离42
算法源码
/* JavaScript Node ACM模式 控制台输入获取 */
const readline = require("readline");
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
const lines = [];
rl.on("line", (line) => {
lines.push(line);
if (lines.length === 2) {
const [str, subStr] = lines;
const points = [];
const idxs = [];
const set = new Set(subStr);
for (let i = 0; i < str.length; i++) {
const char = str[i];
if (set.has(char)) {
points.push(char);
idxs.push(i);
}
}
var dfs = (n, m, path, res) => {
if (path.length === m) {
const pathStr = path.map((p) => points[p]).join("");
if (pathStr === subStr) res.push([...path]);
return;
}
for (let i = 0; i < n; i++) {
path.push(i);
dfs(n, m, path, res);
path.pop();
}
};
const res = [];
dfs(points.length, subStr.length, [], res);
const ans = res
.map((path) => {
const newPath = path.map((p) => idxs[p]);
let sum = newPath[0];
for (let i = 1; i < newPath.length; i++) {
sum += Math.abs(newPath[i] - newPath[i - 1]);
}
return sum;
})
.sort((a, b) => a - b)[0];
console.log(ans);
lines.length = 0;
}
});