【春招笔试】2025.05.08-得物春招研发岗改编题

✅ 春招备战指南 ✅

💡 学习建议:

  • 先尝试独立解题(建议用时:90分钟/套)
  • 对照解析查漏补缺

🧸 题面描述背景等均已深度改编,做法和题目本质基本保持一致。

🍹 感谢各位朋友们的订阅,你们的支持是我们创作的最大动力

🌸 目前本专栏已经上线60+套真题改编解析,后续会持续更新的

春秋招合集 -> 互联网必备刷题宝典🔗

题目一:螺旋迷宫蛇行挑战

1️⃣:分析螺旋路径可能的碰撞情况

2️⃣:根据路径片段长度关系,判断是否会相撞

难度:中等

这道题目的关键在于理解只能向右转的螺旋路径特性,并分析可能出现的碰撞情况。通过数学关系分析,我们可以得到判断碰撞的条件,从而实现O(n)的高效解法,避免了复杂的路径模拟。

题目二:魔法水晶共振组合

1️⃣:分析三个数两两相乘为完全平方数的数学性质

2️⃣:将每个数拆分为无平方因子部分和平方因子部分

3️⃣:统计无平方因子部分相同的数量,计算组合数

难度:中等偏难

这道题目结合了数论知识和组合计数。通过理解完全平方数的性质,发现满足条件的三元组必须具有相同的无平方因子部分。利用埃氏筛和质因数分解,可以高效地找出所有满足条件的三元组数量。

题目三:矩阵魔法变换

1️⃣:分析L形区域操作的特点和影响

2️⃣:对于足够大的矩阵,每次操作改变3个单元格的值

3️⃣:检查总和是否能被3整除或特殊情况判断

难度:中等

这道题目需要洞察矩阵操作的数学本质。关键发现是:当矩阵足够大时,每次操作影响3个单元格,因此总和必须能被3整除才可能全部变为0。对于特殊情况(如行列数小于2),需要单独判断。这种解法将复杂问题简化为简单的数学关系判断。

01. 螺旋迷宫蛇行挑战

问题描述

小基 最近开发了一款创新的迷宫游戏,在这个游戏中,玩家控制的是一条只能向右转弯的蛇形机器人。这意味着机器人的移动轨迹呈现单螺旋结构,如下图所示:

image

小基 将机器人的移动路径记录为一系列直线段长度,即每次直行 的长度后,右转 90 度继续前进。现在,小基 想要确定机器人是否会在移动过程中撞到自己之前的路径。

输入格式

第一行输入测试用例的个数

对于每一组测试用例,第一行输入机器人路径的段数

随后一行给出 个正整数 ,表示每一段直线的长度。

输出格式

对于每一组测试用例,单独输出一行字符串。

若机器人会撞到自身路径,输出"",否则输出""。

样例输入

1
6
5 7 11 12 16 17
1
6
2 3 4 4 7 7

样例输出

NO
NO

数据范围

样例 解释说明
样例1 机器人按照给定的路径长度移动,不会与自己之前的路径相撞
样例2 机器人同样不会与自己的路径相撞

题解

这道题目考察的是判断一条按照特定规则移动的"蛇"是否会与自身相撞。

首先,我们需要理解题目中的单螺旋结构:机器人只能向右转弯(顺时针旋转90度),形成一个从内到外的螺旋。给定的数组表示机器人每一段直线移动的长度,之后就会右转。

判断是否相撞,本质上是检查新的移动路径是否会与之前的路径相交。对于这种螺旋形状,有几种典型的碰撞情况:

  1. 当前段与前前段相撞:第i段长度大于等于第(i-2)段,同时第(i-1)段长度小于等于第(i-3)段
  2. 当前段与更早的段相撞:需要考虑特殊的几何关系

通过分析可能的碰撞场景,我们可以得出几个判断条件:

  • 如果第i段长度 >= 第(i-2)段长度,且第(i-1)段长度 <= 第(i-3)段长度,则会相撞
  • 如果第(i-1)段长度等于第(i-3)段长度,且第i段长度 + 第(i-4)段长度 >= 第(i-2)段长度,则会相撞
  • 还有更复杂的情况:当第(i-2)段长度 >= 第(i-4)段长度,且第i段长度 >= 第(i-2)段长度 - 第(i-4)段长度,同时第(i-1)段长度在一定范围内时,也会相撞

时间复杂度为O(N),对于给定的数据范围(N最大为10^5)完全可以接受。这种方法避免了模拟整个路径的复杂性,而是通过纯数学关系判断是否会相撞。

参考代码

  • Python
import sys
input = lambda:sys.stdin.readline().strip()

def can_hit(lens):
    # 判断是否会碰撞的函数
    for i in range(3, len(lens)):
        # 情况1: 当前段与前前段碰撞
        if lens[i] >= lens[i-2] and lens[i-1] <= lens[i-3]:
            return True
        # 情况2: 特殊情况处理
        if i >= 4 and lens[i-1] == lens[i-3] and lens[i] + lens[i-4] >= lens[i-2]:
            return True
        # 情况3: 更复杂的几何关系
        if (i >= 5 and lens[i-2] >= lens[i-4] and 
            lens[i] >= lens[i-2] - lens[i-4] and
            lens[i-1] >= lens[i-3] - lens[i-5] and 
            lens[i-1] <= lens[i-3]):
            return True
    return False

def main():
    # 读取测试用例数
    t = int(input())
    for _ in range(t):
        # 读取路径段数
        n = int(input())
        # 读取每段长度
        lens = list(map(int, input().split()))
        # 判断并输出结果
        print("Yes" if can_hit(lens) else "NO")

if __name__ == "__main__":
    main()
  • Cpp
#include <bits/stdc++.h>
using namespace std;
using ll = long long;

// 判断蛇是否会撞到自身
bool check_collision(const vector<ll>& lens) {
    for (int i = 3; i < lens.size(); i++) {
        // 第一种碰撞情况
        if (lens[i] >= lens[i-2] && lens[i-1] <= lens[i-3]) {
            return true;
        }
        // 第二种碰撞情况
        if (i >= 4 && lens[i-1] == lens[i-3] && 
            lens[i] + lens[i-4] >= lens[i-2]) {
            return true;
        }
        // 第三种复杂碰撞情况
        if (i >= 5 && lens[i-2] >= lens[i-4] && 
            lens[i] >= lens[i-2] - lens[i-4] &&
            lens[i-1] >= lens[i-3] - lens[i-5] && 
            lens[i-1] <= lens[i-3]) {
            return true;
        }
    }
    return false;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    int t;
    cin >> t;
    
    while (t--) {
        int n;
        cin >> n;
        
        vector<ll> lens(n);
        for (int i = 0; i < n; i++) {
            cin >> lens[i];
        }
        
        bool hit = check_collision(lens);
        cout << (hit ? "Yes" : "NO") << "\n";
    }
    
    return 0;
}
  • Java
import java.io.*;
import java.util.*;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int t = Integer.parseInt(br.readLine().trim());
        
        for (int tc = 0; tc < t; tc++) {
            int n = Integer.parseInt(br.readLine().trim());
            String[] tokens = br.readLine().trim().split(" ");
            
            long[] lens = new long[n];
            for (int i = 0; i < n; i++) {
                lens[i] = Long.parseLong(tokens[i]);
            }
            
            boolean hit = checkHit(lens);
            System.out.println(hit ? "Yes" : "NO");
        }
    }
    
    // 检查蛇是否会撞到自身
    private static boolean checkHit(long[] lens) {
        for (int i = 3; i < lens.length; i++) {
            // 碰撞条件1
            if (lens[i] >= lens[i-2] && lens[i-1] <= lens[i-3]) {
                return true;
            }
            // 碰撞条件2
            if (i >= 4 && lens[i-1] == lens[i-3] && 
                lens[i] + lens[i-4] >= lens[i-2]) {
                return true;
            }
            // 碰撞条件3
            if (i >= 5 && lens[i-2] >= lens[i-4] && 
                lens[i] >= lens[i-2] - lens[i-4] &&
                lens[i-1] >= lens[i-3] - lens[i-5] && 
                lens[i-1] <= lens[i-3]) {
                return true;
            }
        }
        return false;
    }
}

02. 魔法水晶共振组合

问题描述

在小柯的魔法研究实验室中,有一种特殊的水晶具有奇妙的共振特性。当三块水晶的能量值分别为 时,如果它们两两结合产生的共振能量(即 )都是完美平方能量(即某个整数的平方),那么这三块水晶被称为"共振三元组"。

小柯的实验室里有编号从 的水晶,每块水晶的能量值等于其编号。她想知道在这些水晶中,有多少种不同的共振三元组组合,即满足 都是完全平方数的三元组 的数量。

输入格式

输入一个正整数 ,表示水晶的最大编号。

输出格式

输出一个整数,表示满足条件的共振三元组数量。

样例输入

9
16

样例输出

1
4

数据范围

样例 解释说明
样例1 时,满足条件的三元组只有 ,因为 都是完全平方数
样例2 时,满足条件的三元组有

题解

这道题目要求我们找出满足特定条件的三元组数量。条件是:三个数 两两相乘的结果都是完全平方数。

乍一看,似乎需要枚举所有可能的三元组,但这样会导致 的时间复杂度,对于 最大为 的情况来说太慢了。

仔细分析这个条件,如果 都是完全平方数,那么这三个数有什么共同特性呢?

关键洞察:如果将每个数分解为质因数的乘积,那么当两个数相乘结果为完全平方数时,意味着它们共同的质因数必须出现偶数次。

换个角度思考,我们可以将每个数表示为 ,其中 是无平方因子的部分(squarefree), 是平方因子。对于任意两个数 ,它们的乘积是完全平方数的条件是

基于这个观察,我们可以计算每个 值出现的次数,然后对于每个 值,我们从对应的数中选取3个数的组合数量,即

算法步骤:

  1. 先预处理出每个数的最小质因子(使用埃氏筛法)
  2. 对于每个数 ,计算其无平方因子部分
  3. 统计每个 值出现的次数
  4. 对于每个 值,计算 并累加到答案中

时间复杂度为 ,主要在于质因数分解的过程。空间复杂度为 ,用于存储最小质因子和计数。

参考代码

  • Python
import sys
input = lambda:sys.stdin.readline().strip()

剩余60%内容,订阅专栏后可继续查看/也可单篇购买

互联网刷题笔试宝典 文章被收录于专栏

互联网刷题笔试宝典,这里涵盖了市面上大部分的笔试题合集,希望助大家春秋招一臂之力

全部评论

相关推荐

入职也有段时间了,闲来无事,记录记录参与的平台换了好几波人(前后端方向都一样),整体的发展态势便是:接新需求、重构每天坐下,没有需求的日子便是“熟悉历史(屎?)逻辑”,作为一个实习生,我也没啥资格说他到底是不是💩。经常接口一堆字段,逻辑一堆字段,死无对账。是的,没有接口文档,你没听错;也没有readme,意思全靠猜。那种无力感,你懂我意思?起初我还是斗志满满,觉得如果能在实习这段时间跟着mt在平台有所小成就,也算不枉这段实习。但是他们似乎也是在“赌”以及小心翼翼的不想推动。尽管他们确实在过去半年(一年?)已经做了一些动作有时候整理了一些问题,希望能够得到解答,得到的也是“这些历史逻辑,你问我我也只能告诉你我也不清楚,我也只能靠猜”(尬笑😅);不然就是,这部分逻辑你不需要去深究每部分的细节,知道哪个数据在哪里处理的即可...再有激情和热情,说白了也被浇灭了,倒是每天得为日报内容发愁(唯一期待的就剩每天傍晚健个身、吃个饭)我惊叹于为什么有人写的代码根本就没有所谓的单向数据流(常常在意想不到的地方进行了改动)、根本就没有所谓的cr、根本就没有规范性可言,然后留给后来者的只有唏嘘和更多的成本(作为一个实习生而言,能发出这种疑问,那代码真的是无敌了)我无法站在一个旁观者的角度去谴责历代开发者的佳作,毕竟他们当时可能是处在一个高压、短期的环境下完成的,毕竟人和代码总要跑通一个但其实,更多的是,意识到以后我工作了也是接触这些?那我感觉是真的对之后无感我深刻的意识到到了哪都是一个草台班子,是我的期待值过高,于是想逃,但发现根本无处可去,才意识到都tm一个鸟样...#我的实习日记##牛客解忧铺#
点赞 评论 收藏
分享
评论
1
1
分享

创作者周榜

更多
牛客网
牛客企业服务