2018网易游戏雷火盘古实习生招聘笔试真题

2月15号参加的网易游戏实习在线笔试(内推),以为会考小题的,背了一天计算机网络和操作系统,结果拿到题只有4道编程大题,囧~如果没有一点算法竞赛的知识,想拿下来还是挺困难的。(网易游戏应该算国内笔试很难的了)



1.字符串编码

输入描述:
每个测试输入包含1个测试用例
每个测试用例输入只有一行字符串,字符串只包括大写英文字母,长度不超过10000。


输出描述:
输出编码后的字符串

输入例子:
AAAABCCDAA

输出例子:
4A1B2C1D2A

思路分析:这道题好像以前是一家企业的面试题,LeetCode Easy级别,思路弄清楚,10分钟AC。

#include <cstdio>
#include <string>
#include <iostream>

using namespace std;

string num = "0123456789";

string intToString( int n ) {
    string str = "";
    while( n ) {
        str = num[n % 10] + str;
        n = n / 10;
    }

    return str;
}

string solve( string str ) {
    int len = str.size();
    int i = 0;
    char cur;
    int cnt;
    string ans = "";
    while( i < len ) {
        cur = str[i];
        cnt = 0;
        int j = 0;
        for( j = i; j < len; j++ ) {    // 从当前位置开始检索
            if( str[j] == cur ) {
                cnt++;
            }
            else if( str[j] != cur ) {
                ans = ans + intToString( cnt );
                ans = ans + cur;
                i = j;                      // 从i = j这个位置再开始检索
                //cout << ans << endl;
                break;
            }
        }
        if( j == len ) {
            ans = ans + intToString( cnt );
            ans = ans + cur;
            //cout << ans << endl;
            break;
        }
    }

    return ans;
}

int main() {
    string str;

    while( cin >> str ) {
        string ans = solve( str );
        cout << ans << endl;
    }

    return 0;
}


2.最大和

输入描述:
每个测试输入包含1个测试用例,第一行包括两个整数 N 和 D :
3 <= N <= 100
1 <= D <= N
接下来有N行,每行N个数字d:
0 <= d <= 100


输出描述:
输出一个整数,表示找到的和的最大值

输入例子:
4 2
87 98 79 61
10 27 95 70
20 64 73 29
71 65 15 0

输出例子:
193

思路分析:这道题数据量比较小,只有100,所以暴力枚举即可(注意要搞清楚逻辑再写,写40多分钟都有可能的)。另外可以用dp的想法,维护前缀和。

#include <cstdio>

#define MAX 100 + 10

int Max = 0;

bool check1( int x, int y, int d, int n ) {
    if( x + d - 1 > n ) return false;
    if( y + d - 1 > n ) return false;
    return true;
}


bool check2( int x, int y, int d, int n ) {
    if( x + d - 1 > n ) return false;
    if( y - d < 0 ) return false;
    return true;
}

int main() {
    //freopen( "123.txt", "r", stdin );
    int n, d;

    while( scanf( "%d%d", &n, &d ) != EOF ) {
        Max = 0;
        int arr[MAX][MAX];

        for( int i = 1; i <= n; i++ ) {
            for( int j = 1; j <= n; j++ ) {
                scanf( "%d", &arr[i][j] );
            }
        }

        // 先从每行开始找
        for( int row = 1; row <= n; row++ ) {
            for( int i = 1; i <= n - d + 1; i++ ) {
                int sum = 0;
                for( int j = i; j < d + i; j++ ) {
                    //printf( "add %d %d\n", row, j );
                    sum = sum + arr[row][j];
                }
                if( sum > Max ) Max = sum;
                //printf( "%d\n", sum );
            }
        }

        // 再从每列开始找
        for( int col = 1; col <= n; col++ ) {
            for( int i = 1; i <= n - d + 1; i++ ) {
                int sum = 0;
                for( int j = i; j < d + i; j++ ) {
                    //printf( "add %d %d\n", j, col );
                    sum = sum + arr[j][col];
                }
                if( sum > Max ) Max = sum;
                //printf( "%d\n", sum );
            }
        }

        // 再从左上到右下对角线开始找
        for( int i = 1; i <= n; i++ ) {
            for( int j = 1; j <= n; j++ ) {     // 从i,j起点开始找
                int x = i;
                int y = j;
                if( check1( x, y, d, n ) ) {
                    //printf( "从 %d %d开始\n", x, y );
                    int cnt = 0;
                    int sum = 0;
                    while( cnt < d ) {
                        sum = sum + arr[x][y];
                        cnt++;
                        x++;
                        y++;
                    }
                    //printf( "%d\n", sum );
                    if( sum > Max ) Max = sum;
                }
            }
        }


        // 再从右上到左下对角线开始找
        for( int i = 1; i <= n; i++ ) {
            for( int j = 1; j <= n; j++ ) {     // 从i,j起点开始找
                int x = i;
                int y = j;
                if( check2( x, y, d, n ) ) {
                    //printf( "从 %d %d开始\n", x, y );
                    int cnt = 0;
                    int sum = 0;
                    while( cnt < d ) {
                        sum = sum + arr[x][y];
                        cnt++;
                        x++;
                        y--;
                    }
                    if( sum > Max ) Max = sum;
                    //printf( "%d\n", sum );
                }
            }
        }

        printf( "%d\n", Max );
    }

    return 0;
}


3.推箱子

大家一定玩过“推箱子”这个经典的游戏。具体规则就是在一个N*M的地图上,有1个玩家、1个箱子、1个目的地以及若干障碍,其余是空地。玩家可以往上下左右4个方向移动,但是不能移动出地图或者移动到障碍里去。如果往这个方向移动推到了箱子,箱子也会按这个方向移动一格,当然,箱子也不能被推出地图或推到障碍里。当箱子被推到目的地以后,游戏目标达成。现在告诉你游戏开始是初始的地图布局,请你求出玩家最少需要移动多少步才能够将游戏目标达成。 

输入描述:
每个测试输入包含1个测试用例
第一行输入两个数字N,M表示地图的大小。其中0<N,M<=8。
接下来有N行,每行包含M个字符表示该行地图。其中 . 表示空地、X表示玩家、*表示箱子、#表示障碍、@表示目的地。
每个地图必定包含1个玩家、1个箱子、1个目的地。


输出描述:
输出一个数字表示玩家最少需要移动多少步才能将游戏目标达成。当无论如何达成不了的时候,输出-1。

输入例子:
4 4
....
..*@
....
.X..
6 6
...#..
......
#*##..
..##.#
..X...
.@#...

输出例子:
3
11

思路分析:考查搜索。但是我当时没写出来,这道题只过了3个测试点。说一下别人的思路:

1.DFS,不知道他怎么写的,判断条件应该比较复杂吧。

2.BFS,四维BFS,增加两个维度代表箱子的位置(我当时考试只想到三维了,没想到四维,豁然开朗。。下去再练练)

去年有一道也是推箱子,不过那个是纯模拟,简单一点。有兴趣的可以在hihoCoder上看一下。

(代码暂时没有)


4.赛马

在一条无限长的跑道上,有N匹马在不同的位置上出发开始赛马。当开始赛马比赛后,所有的马开始以自己的速度一直匀速前进。每匹马的速度都不一样,且全部是同样的均匀随机分布。在比赛中当某匹马追上了前面的某匹马时,被追上的马就出局。 请问按以上的规则比赛无限长的时间后,赛道上剩余的马匹数量的数学期望是多少 

输入描述:
每个测试输入包含1个测试用例
输入只有一行,一个正整数N
1 <= N <= 1000


输出描述:
输出一个浮点数,精确到小数点后四位数字,表示剩余马匹数量的数学期望

输入例子:
1
2

输出例子:
1.0000
1.5000

思路分析:题目看上去有点费解,个人更感觉像是一道智力题。我们假设有N匹马赛跑,最后剩下的那个是冠军。注意题目中说每个马的速度不一样,这就说明最后只会剩下一个马,不可能出现并列的情况。另外数学期望的意思就是如果这匹马的编号是i,那P(i)表示i是冠军的概率,就是数学期望。可以这样想一下:如果只有一匹马,那么这匹马肯定是冠军,数学期望显然是1。如果有两匹马,那么某一匹马是冠军的概率是0.5,某一时刻其中一个马被淘汰了,那么另一个马的数学期望变成1,相加就是1.5。依次类推,如果刚开始有N匹马,P(i) = 1 / N,某一时刻P(i) = 1 / (N - 1)、1/(N - 2)......所以这道题的答案就是计算1 + 1  /  2 + 1 / 3 + 1 / 4 + ... + 1 / N的和,就是调和级数。

另外见群里有ACM大神说根据某某定理,先打个表,然后高精度运算得出结果,没听懂他的做法。我感觉调和级数这个还是好理解的。


#include <cstdio>

int main() {
    int n;
    while( scanf( "%d", &n ) != EOF ) {
        double sum = 0.0;
        for( int i = 1; i <= n; i++ ) {
            sum = sum + 1.0 / i;
        }
        printf( "%.4lf\n", sum );
    }
    return 0;
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值