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;
}