【秋招笔试】2025.08.31网易秋招机考笔试真题改编
✅ 秋招备战指南 ✅
💡 学习建议:
- 先尝试独立解题
- 对照解析查漏补缺
🧸 题面描述背景等均已深度改编,做法和题目本质基本保持一致。
🍹 感谢各位朋友们的订阅,你们的支持是我们创作的最大动力
🌸 目前本专栏已经上线160+套真题改编解析,后续会持续更新的
春秋招笔试机考招合集 -> 互联网必备刷题宝典🔗
网易
题目一:魔法师小柯的传送阵实验
1️⃣:模拟执行指令序列,维护位置、朝向和法阵能量点集合
2️⃣:对于瞬移术指令,计算曼哈顿距离找到最近的法阵能量点
3️⃣:根据跳跃规则正确处理指令跳过机制
难度:中等
这道题目的关键在于理解瞬移术的复杂规则,特别是指令跳过机制。需要仔细模拟每一步操作,维护好状态,并正确实现曼哈顿距离的计算和优先级选择。通过暴力枚举法阵能量点,可以在 O(nm) 时间复杂度内解决问题。
题目二:小兰的双重空间闯关
1️⃣:观察到两个角色位置始终相同,简化状态空间为四维
2️⃣:使用BFS算法求解最短路径,同时维护生命值状态
3️⃣:处理陷阱移动规则,确保生命值消耗后仍大于0
难度:中等偏难
这道题目需要理解同步移动的约束条件,将二维坐标问题转化为四维状态空间的BFS问题。关键是正确处理陷阱的移动规则和生命值约束,并在相同步数下选择生命值和最大的方案。状态空间约67万,BFS可以高效求解。
01. 魔法师小柯的传送阵实验
问题描述
小柯是魔法学院的研究生,正在进行传送阵系统的实验。她需要在一个魔法坐标系中操控魔法傀儡,完成指定的法阵收集任务。
在一个无限范围的魔法坐标网格上,分布有 个两两位置不同的"法阵能量点",傀儡的初始位置在
,初始朝向为南方。记当前位置为
,则:
-
向东走一格,位置变为
-
向南走一格,位置变为
-
向西走一格,位置变为
-
向北走一格,位置变为
小柯预设了一条长度为 的魔法指令序列让傀儡执行。指令序列由
、
与
三种法术操作组成:
-
:向当前朝向移动一格,若落在法阵能量点位置则收集该能量点
-
:顺时针旋转
-
:触发"瞬移术",按如下步骤执行:
-
若当前无未收集的法阵能量点,则忽略该指令
-
在剩余法阵能量点中,选取距离当前位置曼哈顿距离最小的点;若有多点,优先横坐标最小,再优先纵坐标最小
-
记所选法阵能量点到当前位置的曼哈顿距离为
,删除前剩余法阵能量点数为
-
瞬移至该法阵能量点并收集之
-
跳过随后
条指令;若剩余指令不足,则执行完即停机
-
输出傀儡执行完所有指令后所在的坐标。
【名词解释】
曼哈顿距离:在平面上,点 与
的曼哈顿距离定义为
。
输入格式
每个测试文件均包含多组测试数据。第一行输入一个整数 代表数据组数,每组测试数据描述如下:
第一行输入两个整数 ,表示法阵能量点数、指令长度。
第二行输入一个长度为 、仅由字符
、
、
构成的字符串
,表示指令序列。
此后 行,第
行输入两个整数
,表示第
个法阵能量点的坐标。
除此之外,保证 个法阵能量点两两位置不同。
输出格式
对于每组测试数据,新起一行,输出两个整数 ,代表傀儡执行完所有指令后所在的坐标。
样例输入
3
2 9
SFFFTFSFF
-2 0
-1 1
2 6
SFFFTF
-2 0
-1 1
2 3
SFF
-2 0
-1 1
样例输出
-2 1
-3 1
-2 0
样例 | 解释说明 |
---|---|
样例1 | 执行第一个指令 |
样例2 | 样例1的子集,最终停在 |
样例3 | 样例1的子集,最终停在 |
数据范围
题解
这道题本质上是一个带有特殊跳跃机制的模拟题。关键在于理解瞬移术的规则和跳跃指令的机制。
首先分析题目的核心操作:
- 基本移动:F 指令让傀儡按当前朝向前进一格,T 指令让傀儡顺时针旋转 90 度
- 瞬移机制:S 指令触发瞬移,需要找到距离最近的法阵能量点,并跳过后续指令
解题思路如下:
状态维护:需要维护傀儡当前位置 、朝向
和剩余的法阵能量点集合。朝向可以用 0=东、1=南、2=西、3=北 来表示。
指令处理:
- T 指令:直接更新朝向
dir = (dir+1) % 4
- F 指令:根据朝向更新位置,然后检查是否踩到法阵能量点,如果是则移除
- S 指令:这是最复杂的部分,需要暴力枚举所有剩余法阵能量点,找到曼哈顿距离最小的那个
瞬移规则详解:
- 如果没有剩余法阵能量点,直接忽略
- 遍历所有剩余法阵能量点,计算曼哈顿距离
- 选择距离最小的点,如果有多个则按题目要求选择 x 最小的,再选择 y 最小的
- 瞬移到该点并移除该法阵能量点
- 跳过后续
条指令,其中
是距离,
是删除前的法阵能量点数量
实现细节:
- 使用向量存储剩余的法阵能量点,便于动态删除
- 在主循环中处理指令,注意 S 指令可能让指令指针跳跃
- 坐标可能超出 int 范围,建议使用 long long
时间复杂度分析:最坏情况下每次 S 指令都要遍历所有法阵能量点,总复杂度为 ,完全可以接受。
参考代码
- Python
import sys
input = lambda: sys.stdin.readline().strip()
# 四个方向:东、南、西、北
dx = [1, 0, -1, 0]
dy = [0, -1, 0, 1]
def solve():
n, m = map(int, input().split())
cmd = input().strip()
# 读取法阵能量点坐标
pts = []
for _ in range(n):
x, y = map(int, input().split())
pts.append([x, y])
x, y = 0, 0 # 初始位置
dir_idx = 1 # 初始朝向南
i = 0
while i < m:
op = cmd[i]
if op == 'T':
# 顺时针旋转90度
dir_idx = (dir_idx + 1) % 4
i += 1
elif op == 'F':
# 向当前朝向移动一格
x += dx[dir_idx]
y += dy[dir_idx]
# 检查是否踩到法阵能量点
for j in range(len(pts)):
if pts[j][0] == x and pts[j][1] == y:
pts.pop(j)
break
i += 1
else: # op == 'S'
if not pts:
i += 1
continue
# 找到曼哈顿距离最小的法阵能量点
best_dist = float('inf')
best_idx = -1
for j in range(len(pts)):
dist = abs(pts[j][0] - x) + abs(pts[j][1] - y)
if (dist < best_dist or
(dist == best_dist and pts[j][0] < pts[best_idx][0]) or
(dist == best_dist and pts[j][0] == pts[best_idx][0] and pts[j][1] < pts[best_idx][1])):
best_dist = dist
best_idx = j
# 瞬移到目标点
x = pts[best_idx][0]
y = pts[best_idx][1]
# 记录删除前的法阵能量点数量
m1 = len(pts)
pts.pop(best_idx)
# 跳过后续指令
skip = min(best_dist, m1)
i += 1 + skip
return x, y
T = int(input())
for _ in range(T):
x, y = solve()
print(x, y)
- Cpp
#include <bits/stdc++.h>
using namespace std;
struct Point {
int x, y;
};
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int T;
cin >> T;
// 四个方向:东、南、西、北
const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, -1, 0, 1};
while (T--) {
int n, m;
cin >> n >> m;
string ops;
cin >> ops;
vector<Point> pts(n);
for (int i = 0; i < n; i++) {
cin >> pts[i].x >> pts[i].y;
}
long long x = 0, y = 0; // 当前位置
int dir = 1; // 初始朝向南
for (int i = 0; i < m; ) {
char op = ops[i];
if (op == 'T') {
// 顺时针旋转90度
dir = (dir + 1) & 3;
i++;
} else if (op == 'F') {
// 向当前朝向移动一格
x += dx[dir];
y += dy[dir];
// 检查是否踩到法阵能量点
for (size_t j = 0; j < pts.size(); j++) {
if (pts[j].x == x && pts[j].y == y) {
pts.erase(pts.begin() + j);
break;
}
}
i++;
} else { // op == 'S'
if (pts.empty()) {
i++;
continue;
}
// 找到曼哈顿距离最小的法阵能量点
int best_idx = 0;
long long best_dist = LLONG_MAX;
for (size_t j = 0; j < pts.size(); j++) {
long long dist = abs((long long)pts[j].x - x) + abs((long long)pts[j].y - y);
if (dist < best_dist ||
(dist == best_dist && pts[j].x < pts[best_idx].x) ||
(dist == best_dist && pts[j].x == pts[best_idx].x && pts[j].y < pts[best_idx].y)) {
best_dist = dist;
best_idx = j;
}
}
// 瞬移到目标点
x = pts[best_idx].x;
y = pts[best_idx].y;
// 记录删除前的法阵能量点数量
long long m1 = pts.size();
pts.erase(pts.begin() + best_idx);
// 跳过后续指令
long long skip = min(best_dist, m1);
i += 1 + skip;
}
}
cout << x << " " << y << "\n";
}
return 0;
}
- Java
import java.io.*;
import java.util.*;
public class Main {
static class Point {
int x, y;
Point(int x, int y) {
this.x = x;
this.y = y;
}
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int T = Integer.parseInt(br.readLine());
// 四个方向:东、南、西、北
int[] dx = {1, 0, -1, 0};
int[] dy = {0, -1, 0, 1};
while (T-- > 0) {
String[] firstLine = br.readLine().split(" ");
int n = Integer.parseInt(firstLine[0]);
int m = Integer.parseInt(firstLine[1]);
String ops = br.readLine();
List<Point> pts = new ArrayList<>();
for (int i = 0; i < n; i++) {
String[] coords = br.readLine().split(" ");
int x = Integer.parseInt(coords[0]);
int y = Integer.parseInt(coords[1]);
pts.add(new Point(x, y));
}
long x = 0, y = 0; // 当前位置
int dirIdx = 1; // 初始朝向南
for (int i = 0; i < m; ) {
char op = ops.charAt(i);
if (op == 'T') {
// 顺时针旋转90度
dirIdx = (dirIdx + 1) % 4;
i++;
} else if (op == 'F') {
// 向当前朝向移动一格
x += dx[dirIdx];
y += dy[dirIdx];
// 检查是否踩到法阵能量点
for (int j = 0; j < pts.size(); j++) {
if (pts.get(j).x == x &&
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
互联网刷题笔试宝典,这里涵盖了市面上大部分的笔试题合集,希望助大家春秋招一臂之力