1. 程式人生 > >2018網易遊戲雷火盤古實習生招聘筆試真題

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...
[email protected]#...

輸出例子:
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;
}