2025校招4399游戏客户端开发工程师部分笔试题解析

单选题

1.存储稀疏矩阵时,以下哪种方式对内存较优(D)

A.散列

B.最小堆

C.二维数组

D.三元组

2.对n个基本有序的整数进行排序,采用插入排序算法和快速排序算法的时间复杂度分别是:(D)

A.O(n^2)和O(nlogn)

B.O(n2)和O(n2)

C.O(n)和O(nlogn)

D.O(n)和O(n^2)

3.在一个抽卡系统中,抽到稀有卡的概率是1/4,且如果连续两次没抽到稀有卡,第三次必定抽到稀有卡,那么抽到稀有卡的实际概率是(B)

A.9/37

B.16/37

C.23/37

D.30/37

解析

状态定义

  • 状态0:当前抽卡前未连续失败(如首次抽卡或最近一次抽卡成功)
  • 状态1:当前抽卡前最近一次失败
  • 状态2:当前抽卡前已连续两次失败(触发保底)

状态转移规则

从状态0:

  • 抽中成功(概率1/4)→ 回到状态0
  • 抽中失败(概率3/4)→ 进入状态1

从状态1:

  • 抽中成功(概率1/4)→ 回到状态0
  • 抽中失败(概率3/4)→ 进入状态2

从状态2:

  • 必中成功(概率100%)→ 回到状态0

列出稳态概率方程

  • π₀ = (1/4)π₀ + (1/4)π₁ + 1·π₂
  • π₁ = (3/4)π₀
  • π₂ = (3/4)π₁
  • π₀ + π₁ + π₂ = 1

解方程得稳态分布

  • π₀ = 16/37(状态0概率)
  • π₁ = 12/37(状态1概率)
  • π₂ = 9/37(状态2概率)

抽到稀有卡的概率:

= 1/4 * 16/37 + 1/4 * 12/37 + 1 * 9/37
= 4/37 + 3/37 + 9/37 = 16/37

4. 在32位平台下,以下这个MyUnion的sizeof大小是多少?(A)

union MyUnion{
struct {
char a;
double b;
}s1;
struct{
int c;
float d;
}s2;
};

A.16

B.24

C.8

D.12

5.在轮转调度算法中,时间片长度过短会导致什么问题?(C)

A.任务饥饿

B.平均等待时间增加

C.系统开销增加

D.任务响应时间变长

6.关于C++中的多态,以下哪种描述是正确的?(D)

A. override关键字可以用于声明多态函数

B.多态不能通过基类指针或引用调用派生类覆盖的虚函数

C. super关键字可以显式地调用基类的成员函数

D.如果一个类包含至少一个纯虚函数,则不能直接实例化

解析

多态函数本身是由 virtual 关键字在基类中声明的。C++ 的多态性正是通过基类指针或引用调用派生类覆盖的虚函数实现的,这是运行时多态的核心机制。在 C++ 中,没有 super 关键字。

7.在TCP拥塞控制中,拥塞避免阶段使用哪种算法来调整拥塞窗口?( C )

A.快速重传算法

B.慢启动算法

C.加性增、乘性减(AIMD)算法

D.快速恢复算法

8.某游戏正在升级一套管理系统。该系统用于在数据库中管理玩家的战力、积分、装备数据。系统经重新整合后,开发人员决定不再使用一张备份数据表scoreinfo表,需永久删除。请选出符合要求的语句:(A)

A. DROP TABLE scoreinfo

B. DROP FROM TABLE scoreinfo

C. DELETE TABLE scoreinfo

D. DELETE FROM TABLE scoreinfo

9.以下哪个不是常见的抗锯齿算法:(B)

A. SMAA子像素增强抗锯齿

B. RTAA光线追踪抗锯齿

C. FXAA快速近似抗锯齿

D. MSAA多重采样抗锯齿

解析

光线追踪带来的抗锯齿效果是其渲染方法的自然结果,而不是一个独立的算法。

10. 以下哪种技术能最有效减少机器学习模型的过拟合?( C )

A.使用更复杂的模型

B.数据标准化

C.正则化

D.增加训练数据

编程题

1.假设有一类数字num,可以表示为num = a8*(10^7) + a7*(10^6) + …+ a2*(10^1) + a1。其中a1~a8为不大于7的非负整数。请设计一个算法,计算这一类数字中,一共有多少个奇数?

题解
public class Main {
    public static void main(String[] args){
        int num_a1 = 4;
        int num_a2_a8 = (int)Math.pow(8,7);
        long ans = num_a1*num_a2_a8;
        System.out.println(ans);
    }
}

2.在一个二维网格中,有一个起点S、一个终点E和一个必须经过的中间点M。网格中的障碍物用#表示,空地用.表示。每次可以向上、下、左、右移动一格。请实现一个算法,找到从起点到终点且经过中间点的最短路径长度。如果无法到达终点,则返回-1。

示例

输入:

4 4
S..M
##.#
….
.##E

输出:

8

题解:
import java.util.*;

class Point{
    int x;
    int y;
    public Point(int x,int y){
        this.x = x;
        this.y = y;
    }
}

public class Main {
    private static final int[][] direction = {{0,1},{0,-1},{1,0},{-1,0}};
    private static int row, col;

    public static int bfs(char[][] grid, Point start,Point end){
        boolean[][] visited = new boolean[row][col];
        Queue<Point> queue = new LinkedList<>();
        queue.add(start);
        visited[start.x][start.y]=true;
        int steps = 0;
        while(!queue.isEmpty()){
            int size = queue.size();
            for(int i=0;i<size;i++){
                Point cur = queue.poll();
                if(cur.x==end.x&&cur.y==end.y){
                    return steps;
                }

                for(int[] dir:direction){
                    int nextX = cur.x+dir[0];
                    int nextY = cur.y+dir[1];
                    if(nextX>=0 && nextX<row&&nextY>=0&&nextY<col&&grid[nextX][nextY]!='#'&&!visited[nextX][nextY]){
                        queue.add(new Point(nextX,nextY));
                        visited[nextX][nextY]=true;
                    }
                }
            }
            steps++;
        }
        return -1;
    }


    public static void main(String[] args){
        Scanner in = new Scanner(System.in);
        row = in.nextInt();
        col = in.nextInt();
        in.nextLine();
        char[][] grid = new char[row][col];
        Point start = null,middle = null,end = null;
        for(int i=0;i<row;i++){
            String line = in.nextLine();
            for(int j=0;j<col;j++){
                grid[i][j] = line.charAt(j);
                if(grid[i][j]=='S'){
                    start = new Point(i,j);
                }else if(grid[i][j]=='M'){
                    middle = new Point(i,j);
                }else if(grid[i][j]=='E'){
                    end = new Point(i,j);
                }
            }
        }

        int ans1 =bfs(grid,start,middle);
        if(ans1 == -1){
            System.out.println(-1);
            return;
        }
        int ans2 =bfs(grid,middle,end);
        if(ans2 == -1){
            System.out.println(-1);
            return;
        }
        System.out.println(ans1+ans2);

    }
}

3.有一排宝石(共M个),每个宝石都有一个能量值。你可以选择任意连续K个宝石合并成一个新的宝石,新宝石保持在原队列的位置且它的能量值是这K个宝石能量值之和。其中有一个幸运值,合并后的能量会直接添加到幸运值上;给定一个幸运值N=0、一堆包含能量值的宝石,你的任务是找到将所有宝石合并成一个宝石的最大幸运值。

要求:

2<=K<=M;

【示例一】

输入:

可连续合并的宝石数K:K=4

宝石具体能量值:[10, 7, 2, 6, 5, 11, 8];

输出:

79

【示例二】

输入:

可连续合并的宝石数K:K=3

宝石具体能量值:[10, 7, 2, 6, 5, 11];

输出:

-1

解释:合并到最后剩余宝石数量=2<K,因此合成失败返回-1。

【示例三】

输入:

可连续合并的宝石数K:K=2

宝石具体能量值:[6,5,4,1,0,5,7];

输出:

107

题解
public class Main{

    public static int solve(int K, int[] gems) {
        int M = gems.length;
        if (M < K) {
            return -1;
        }

        long[][] dp = new long[M][M]; // dp[i][j]: 合并 gems[i...j] 的最大幸运值
        long[] prefixSum = new long[M + 1]; // 前缀和,用于快速计算区间和

        // 计算前缀和
        for (int i = 0; i < M; i++) {
            prefixSum[i + 1] = prefixSum[i] + gems[i];
        }

        // 区间长度从小到大进行迭代
        for (int len = K; len <= M; len++) {
            for (int i = 0; i <= M - len; i++) {
                int j = i + len - 1; // 区间右端点

                // 遍历所有可能的分割点
                for (int k = i; k < j; k++) {
                    dp[i][j] = Math.max(dp[i][j], dp[i][k] + dp[k + 1][j]); // 分为两段
                }
                //如果当前区间能够合并
                if((len - 1) % (K-1) == 0){
                    dp[i][j] += prefixSum[j + 1] - prefixSum[i]; // 加上合并后的幸运值
                }


            }
        }


        if ((M - 1) % (K - 1) != 0) {
            return -1;
        }

        return (int) dp[0][M - 1];
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值