当前位置: 首页 > 面试经验 >

【秋招突围】2024届秋招-OPPO笔试题-第二套

优质
小牛编辑
99浏览
2024-07-27

【秋招突围】2024届秋招-OPPO笔试题-第二套

大家好这里是清隆学长 ,一枚热爱算法的程序员

✨ 本系列打算持续跟新 OPPO 春秋招笔试题 汇总

今天 OPPO2025届秋招 也是正式拉开帷幕啦

感谢大家的订阅➕ 和 喜欢

✨ 笔试合集传送们 -> 春秋招笔试合集

✨ 01.LYA 的魔法方阵

问题描述

LYA 是一位魔法学徒,她掌握了一种神奇的魔法阵,可以快速计算 方阵的行列式的值。然而,LYA 的导师认为仅仅计算行列式的值还不够有趣,他希望 LYA 能够直接构造出行列式等于给定值 方阵。

现在,LYA 想要尝试改进她的魔法阵,使其能够满足导师的要求。你能帮助 LYA 完成这个任务吗?

输入格式

输入仅一行,包含一个正整数 ,表示目标行列式的值。

输出格式

输出一个 的方阵,使其行列式的值等于 。方阵中的元素必须是非负整数且不超过 。如果存在多个满足条件的方阵,输出任意一个即可。

样例输入

5

样例输出

1 1
1 6

数据范围

题解

本题可以通过枚举的方式来解决。我们可以枚举方阵中的四个元素 , , , ,使得 。由于元素的取值范围为 ,因此我们可以使用四重循环来枚举所有可能的组合。

时间复杂度为 ,空间复杂度为

参考代码

  • Python
x = int(input())

for a in range(21):
    for b in range(21):
        for c in range(21):
            for d in range(21):
                if a * d - b * c == x:
                    print(a, b)
                    print(c, d)
                    exit(0)
  • Java
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int x = scanner.nextInt();

        for (int a = 0; a <= 20; a++) {
            for (int b = 0; b <= 20; b++) {
                for (int c = 0; c <= 20; c++) {
                    for (int d = 0; d <= 20; d++) {
                        if (a * d - b * c == x) {
                            System.out.println(a + " " + b);
                            System.out.println(c + " " + d);
                            return;
                        }
                    }
                }
            }
        }
    }
}
  • Cpp
#include <iostream>
using namespace std;

int main() {
    int x;
    cin >> x;

    for (int a = 0; a <= 20; a++) {
        for (int b = 0; b <= 20; b++) {
            for (int c = 0; c <= 20; c++) {
                for (int d = 0; d <= 20; d++) {
                    if (a * d - b * c == x) {
                        cout << a << " " << b << endl;
                        cout << c << " " << d << endl;
                        return 0;
                    }
                }
            }
        }
    }

    return 0;
}

02.卢小姐的舞蹈连击

问题描述

卢小姐是一名热爱跳舞的女孩,她最喜欢的一款舞蹈游戏叫做"舞动青春"。

游戏中卢小姐可以在音乐的节奏下按照屏幕上的舞步提示进行跳舞。每跳对一个舞步就可以获得分数,而"连击"更是这个游戏的亮点:连续跳对舞步可以积攒"连击点",获得的分数为 ( 为基础得分, 为连击加分, 为连击次数)。

卢小姐每次连击成功,都会持续获得更高的分数。但是如果某个舞步跳错,虽然依然可以得到基础分,但是连击数会清零。

现在卢小姐想让你帮忙计算一局游戏中她的总得分。

输入格式

第一行输入三个正整数 ,分别代表本局游戏的总舞步数、基础得分和连击加分。()

第二行输入一个长度为 的字符串,仅包含字符 ox,其中 o 表示这个舞步跳对,x 表示这个舞步跳错。

输出格式

输出一个正整数,表示卢小姐本局游戏的总得分。

样例输入

5 2 1
oxoox

样例输出

14

数据范围

题解

这道题可以用一个变量 来记录当前的连击次数,初始值为0。遍历输入的字符串,对于每一个字符:

  • 如果是 o,说明这个舞步跳对,可以获得 的分数,并且连击次数 加1。
  • 如果是 x,说明这个舞步跳错,只能获得基础分 ,并且连击次数 要重置为0。

遍历结束后,累加的分数就是总得分。

时间复杂度 ,空间复杂度

参考代码

  • Python
n, a, b = map(int, input().split())
steps = input()

score = 0
combo = 0

for step in steps:
    score += a + b * combo
    
    if step == 'o':
        combo += 1
    else:
        combo = 0

print(score)
  • Java
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int a = sc.nextInt();
        int b = sc.nextInt();
        String steps = sc.next();
        
        long score = 0;
        int combo = 0;
        
        for (char step : steps.toCharArray()) {
            score += a + (long) b * combo;
            
            if (step == 'o') {
                combo++;
            } else {
                combo = 0;
            }
        }
        
        System.out.println(score);
    }
}
  • Cpp
#include <iostream>
using namespace std;

int main() {
    int n, a, b;
    cin >> n >> a >> b;
    
    string steps;
    cin >> steps;
    
    long long score = 0;
    int combo = 0;
    
    for (char step : steps) {
        score += a + 1LL * b * combo;
        
        if (step == 'o') {
            combo++;
        } else {
            combo = 0;
        }
    }
    
    cout << score << endl;
    
    return 0;
}

1️⃣ 03.国际象棋骑士的最少步数

问题描述

LYA是一名国际象棋爱好者,最近她在研究骑士的走法。在国际象棋中,骑士可以按照"日"字形的方式移动,即先向水平或垂直方向移动两格,再向垂直或水平方向移动一格,如下图所示:

  _______________
8 |_|_|_|_|_|_|_|_|
7 |_|_|_|_|_|_|_|_|
6 |_|_|X|_|X|_|_|_|
5 |_|X|_|_|_|X|_|_|
4 |_|_|_|*|_|_|_|_|
3 |_|X|_|_|_|X|_|_|
2 |_|_|X|_|X|_|_|_|
1 |_|_|_|_|_|_|_|_|
   a b c d e f g h

其中 表示骑士所在的位置, 表示骑士可以一步到达的位置。

现在LYA想知道,如果骑士从棋盘上的位置 出发,最少需要几步可以到达位置 。注意,棋盘的行号从下到上为 ,列号从左到右为

输入格式

第一行一个整数 ,表示询问组数。

接下来 行,每行包含四个整数 ,分别表示起点和终点的行号和列号。其中列号为 的整数,分别对应

输出格式

对于每组询问,输出一个整数,表示骑士从 的最少步数。

样例输入

4
1 1 1 1
1 1 5 5
1 1 4 1
1 1 -1 -3

样例输出

0
1
2
2

数据范围

题解

本题可以使用BFS或双向BFS来解决。下面使用双向BFS来进行讲解。

首先,我们可以将棋盘上的每个位置看做一个节点,骑士每次可以移动的 个位置看做这个节点的相邻节点。这样,整个棋盘就构成了一个无向图。我们的目标就是在这个图中找到从起点到终点的最短路径。

双向BFS的基本思路是同时从起点和终点开始搜索,当两个搜索在某个节点相遇时,就找到了起点到终点的最短路径。与普通BFS相比,双向BFS可以大大减少搜索的节点数,从而提高搜索效率。

具体实现时,我们可以使用两个队列 分别存储从起点和终点开始搜索的节点,两个哈希表 分别存储从起点和终点开始搜索到每个节点的距离。初始时,将起点加入 ,终点加入 ,并将它们的距离都设为

接下来,我们每次从 中各取出一个节点 ,枚举它们的所有相邻节点 。如果 已经存在于 中,或者 已经存在于 中,则说明我们已经找到了一条从起点到终点的最短路径,返回 即可。否则,如果 不在 中,就将 加入 ,并将 设为 ;如果 不在 中,就将 加入 ,并将 设为

这样,我们就可以在 的时间内求出骑士从起点到终点的最少步数。其中 为棋盘上的节点数,在本题中

参考代码

  • Python
directions = [(1, 2), (1, -2), (2, 1), (2, -1), (-1, 2), (-1, -2), (-2, 1), (-2, -1)]

t = int(input())
for _ in range(t):
    x_start, y_start, x_end, y_end = map(int, input().split())
    delta_x = x_end - x_start
    delta_y = y_end - y_start

    if delta_x == 0 and delta_y == 0:
        print(0)
    elif (abs(delta_x) in (1, 2) and abs(delta_x) + abs(delta_y) == 3) or (delta_x != 0 and abs(delta_x) == abs(delta_y)):
        print(1)
    else:
        if (delta_x + delta_y) % 2 == 0 and (delta_x - delta_y) % 2 == 0:
            print(2)
        else:
            found = False
            for x_dir, y_dir in directions:
                next_x = delta_x + x_dir
                next_y = delta_y + y_dir
                if (abs(next_x) in (1, 2) and abs(next_x) + abs(next_y) == 3) or (next_x != 0 and abs(next_x) == abs(next_y)):
                    found = True
                    break

            print(2 if found else 3)
  • Java
import java.util.Scanner;

public class ChessMoveCalculator {
    private static final int[][] directions = {{1, 2}, {1, -2}, {2, 1}, {2, -1}, {-1, 2}, {-1, -2}, {-2, 1}, {-2, -1}};
    
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int t = scanner.nextInt();
        while (t-- > 0) {
            int xStart = scanner.nextInt();
            int yStart = scanner.nextInt();
            int xEnd = scanner.nextInt();
            int yEnd = scanner.nextInt();
            long deltaX = xEnd - xStart;
            long deltaY = yEnd - yStart;

            if (deltaX == 0 && deltaY == 0) {
                System.out.println(0);
            } else if ((Math.abs(deltaX) == 1 || Math.abs(deltaX) == 2) && Math.abs(deltaX) + Math.abs(deltaY) == 3 || (deltaX != 0 && Math.abs(deltaX) == Math.abs(deltaY))) {
                System.out.println(1);
            } else {
                if ((deltaX + deltaY) % 2 == 0 && (deltaX - deltaY) % 2 == 0) {
                    System.out.println(2);
                } else {
                    boolean found = false;
                    for (int[] direction : directions) {
                        long nextX = deltaX + direction[0];
                        long nextY = deltaY + direction[1];
                        if ((Math.abs(nextX) == 1 || Math.abs(nextX) == 2) && Math.abs(nextX) + Math.abs(nextY) == 3 || (nextX != 0 && Math.abs(nextX) == Math.abs(nextY))) {
                            found = true;
                            break;
                        }
                    }
                    System.out.println(found ? 2 : 3);
                }
            }
        }
        scanner.close();
    }
}
  • Cpp
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;

int main() {
    vector<pair<int, int>> moves{{1, 2}, {1, -2}, {2, 1}, {2, -1}, {-1, 2}, {-1, -2}, {-2, 1}, {-2, -1}};
    int testCases;
    cin >> testCases;
    while (testCases--) {
        int startX, startY, endX, endY;
        cin >> startX >> startY >> endX >> endY;
        long long diffX = endX - startX;
        long long diffY = endY - startY;

        if (diffX == 0 && diffY == 0) {
            cout << 0 << endl;
        } else if ((abs(diffX) == 1 || abs(diffX) == 2) && abs(diffX) + abs(diffY) == 3 || (diffX != 0 && abs(diffX) == abs(diffY))) {
            cout << 1 << endl;
        } else {
            if ((diffX + diffY) % 2 == 0 && (diffX - diffY) % 2 == 0) {
                cout << 2 << endl;
            } else {
                bool found = false;
                for (auto& [moveX, moveY] : moves) {
                    long long nextX = diffX + moveX;
                    long long nextY = diffY + moveY;
                    if ((abs(nextX) == 1 || abs(nextX) == 2) && abs(nextX) + abs(nextY) == 3 || (nextX != 0 && abs(nextX) == abs(nextY))) {
                        found = true;
                        break;
                    }
                }
                cout << (found ? 2 : 3) << endl;
            }
        }
    }
    return 0;
}

#OPPO##OPPO求职进展汇总##秋招##秋招提前批,你开始投了吗#
 类似资料: