網易遊戲(互娛)-遊戲研發/初級遊戲研發/平臺開發崗部分真題彙總 題解
1.時鐘:
題目描述:
小W有一個電子時鐘用於顯示時間,顯示的格式為HH:MM:SS,HH,MM,SS分別表示時,分,秒。其中時的範圍為[‘00’,‘01’…‘23’],分的範圍為[‘00’,‘01’…‘59’],秒的範圍為[‘00’,‘01’…‘59’]。
但是有一天小W發現鐘錶似乎壞了,顯示了一個不可能存在的時間“98:23:00”,小W希望改變最少的數字,使得電子時鐘顯示的時間為一個真實存在的時間,譬如“98:23:00”通過修改第一個’9’為’1’,即可成為一個真實存在的時間“18:23:00”。修改的方法可能有很多,小W想知道,在滿足改變最少的數字的前提下,符合條件的字典序最小的時間是多少。其中字典序比較為用“HHMMSS”的6位字串進行比較。
解題思路分析:
題目的要求非常的明確,就是要我們判斷這個鍾是否是顯示的真實存在的時間,如果不是的話,我們可以通過改變任意一位上的數字,問我們最少需要多少次改動,使得這個時鐘上的時間既能表示真實存在的時間,也能使得整個時鐘的字典序最小。
好的,首先來分析一下什麼情況下時鐘顯示的時間是不存在的,因為不能顯示負數,所以只要小時 >= 24,分、秒 >= 60就是不存在的,注意是>=不是>,小編也因此錯交了一次。那再來分析,如果時間是不存在的,那麼怎麼改是最合理的,因為我們既要時間存在也要字典序最小,不難想到,我們需要做的就是將高位變為0即可,所以我們只需要將錯的地方(H,M,S)的高位改為0就可以得到答案。
程式碼:
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; char str[10]; int main() { int T; scanf("%d", &T); while(T--) { int H, M, S; scanf("%d:%d:%d", &H, &M, &S); if(H >= 24) { H = H%10; } if(M >= 60) { M = M%10; } if(S >= 60) { S = S%10; } printf("%02d:%02d:%02d\n", H, M, S); } return 0; }
2.會話列表
題目描述:
小云正在參與開發一個即時聊天工具,他負責其中的會話列表部分。
會話列表為顯示為一個從上到下的多行控制元件,其中每一行表示一個會話,每一個會話都可以以一個唯一正整數id表示。
當用戶在一個會話中傳送或接收資訊時,如果該會話已經在會話列表中,則會從原來的位置移到列表的最上方;如果沒有在會話列表中,則在會話列表最上方插入該會話。
小云在現在要做的工作是測試,他會先把會話列表清空等待接收資訊。當接收完大量來自不同會話的資訊後,就輸出當前的會話列表,以檢查其中是否有bug。
解題思路分析:
凡是用過聊天工具(QQ,微信等)的人,應該這道題的題意不難理解,題目的要求是說,給我們帶先後順序的發訊息物件,問我們最後的會話列表的訊息物件順序應該是怎麼樣的。
這題我們其實可以反過來做,因為最後傳送訊息的一定是在最上面的,同理倒數第二個傳送訊息的應該是在第二個位置,但是如果出現重複出現的訊息物件,那麼位置肯定是按靠後也就是訊息物件最後一次傳送訊息的時間為準來決定位置,所以我們需要記錄一下訊息物件有沒有出現過即可得到答案。
程式碼:
#include <map>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 200+5;
map<int, int> Map;
int id[maxn], ans[maxn];
int main() {
int T;
scanf("%d", &T);
while(T--) {
int n, num = 0;
cin >> n;
Map.clear();
for(int i=0; i<n; i++) {
cin >> id[i];
}
for(int i=n-1; i>=0; i--) {
if(Map[id[i]] == 0) {
ans[num++] = id[i];
Map[id[i]] = 1;
}
}
for(int i=0; i<num; i++) {
if(i == num-1) {
cout << ans[i] << endl;
}
else {
cout << ans[i] << " ";
}
}
}
return 0;
}
3.字元迷陣:
題目描述:
字元迷陣是一種經典的智力遊戲。玩家需要在給定的矩形的字元迷陣中尋找特定的單詞。
在這題的規則中,單詞是如下規定的:
1. 在字元迷陣中選取一個字元作為單詞的開頭;
2. 選取右方、下方、或右下45度方向作為單詞的延伸方向;
3. 以開頭的字元,以選定的延伸方向,把連續得到的若干字元拼接在一起,則稱為一個單詞。
以圖1為例,如果要在其中尋找單詞"WORD",則綠色框所標示的都是合法的方案,而紅色框所標示的都是不合法的方案。
現在的問題是,給出一個字元迷陣,及一個要尋找的單詞,問能在字元迷陣中找到多少個該單詞的合法方案。注意合法方案是可以重疊的,如圖1所示的字元迷陣,其中單詞"WORD"的合法方案有4種。
解題思路分析:
題意是說,給我們一個矩形和一個字串,讓我們在這個矩陣中找到出現過多少個給我們的字串,且要求匹配的方式只能是從左到又、從上到下、從左上到右下的順序。很明顯這題就是一個換了個形式的字串匹配,本來小編是想用三個方向的KMP來做這道題的,但是仔細一分析,矩陣為100 * 100的,字串大小為10的,匹配方向為3種,那麼直接暴力匹配複雜度也不過就10^5,那麼這題應該不是考察我們的KMP演算法,而是考察我們在矩陣中的三個方向的字串匹配的編碼能力。
程式碼:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 100+5;
int dir[3][2] = {{0,1}, {1,0}, {1,1}};
char Map[maxn][maxn];
char str[10];
int n, m;
bool flag(int x, int y) {
if(x >= n || x < 0 || y >= m || y < 0) {
return false;
}
return true;
}
int main() {
int T;
cin >> T;
while(T--) {
cin >> n >> m;
for(int i=0; i<n; i++) {
cin >> Map[i];
}
cin >> str;
int len = strlen(str), num = 0;
for(int i=0; i<n; i++) {
for(int j=0; j<m; j++) {
if(Map[i][j] == str[0]) {
for(int d=0; d<3; d++) {
int tx = i, ty = j, ok = 1;
for(int k=1; k<len; k++) {
tx += dir[d][0];
ty += dir[d][1];
if(!flag(tx, ty) || Map[tx][ty] != str[k]) {
ok = 0;
break;
}
}
if(ok) {
num++;
}
}
}
}
}
cout << num << endl;
}
}