1. 程式人生 > >完美世界2017C++遊戲開發筆試程式設計題

完美世界2017C++遊戲開發筆試程式設計題

第一題

題意:給出一個序列a,需要找到一對位置(i, j)(j > i),使得a[j] - a[i]的值儘量大,同時i儘量大並且j儘量小,如果任意a[j] - a[i]都<=0,則輸出-1,-1。
題解:從1到n掃一遍序列處理即可,i儘量大用>=,j儘量小用>即可。
程式碼:

#include <cstdio>
#include <iostream>
using namespace std;
#define maxn (1000000)
int a[maxn], prei[maxn];
int main()
{
      int n;
      cin
>> n; for(int i = 0; i < n; i++) { scanf("%d", &a[i]); prei[i] = -1; } int g = -1; for(int i = 0; i < n; i++) { if(g == -1 || a[i] <= a[g]) g = i; if(a[g] < a[i+1]) prei[i+1] = g; } int
d = 0, o = -1; for(int i = 1; i < n; i++) if(prei[i] != -1) { if(a[i] - a[prei[i]] > d) { d = a[i] - a[prei[i]]; o = i; } } if(o == -1) cout << -1 << "," << -1 << endl; else
cout << prei[o] << "," << o << endl; return 0; }

第二題

題意:給出一個序列,玩家需要跟boss進行博弈,玩家先手。每次只能從序列頭或尾取一個值加到自己的得分上,玩家和boss都很聰明,求玩家和boss的最終得分。
題解:可以發現總分不是很大,可以記憶化搜尋。d[i][j]表示當拿到的序列為a[i, j]時,從中的最高得分。轉移方程是d[i][j] = max(a[i] + d[i+1][j], d[i][j-1] + a[j]),向下遞歸併且記錄d[i][j]是否已得到即可(應該算是區間dp?)。
程式碼:

#include <cstdio>
#include <iostream>
using namespace std;
#define maxn (111)
int a[maxn], d[maxn][maxn], vis[maxn][maxn], sum;
void dp(int l, int r, int tot)
{
    if(vis[l][r]) return ;
    if(l == r) { d[l][r] = a[l]; vis[l][r] = 1; return; }
    dp(l + 1, r, tot - a[l]); dp(l, r - 1, tot - a[r]);
    d[l][r] = max(tot - d[l + 1][r], tot - d[l][r - 1]);
    vis[l][r] = 1;
}
int main()
{
    int N;
    cin >> N;
    for(int i = 1; i <= N; i++)
    {
        scanf("%d", &a[i]);
        sum += a[i];
    }

    dp(1, N, sum);
    cout << d[1][N] << " " << sum - d[1][N] << endl;
    return 0;
}