【vivo2019年】算法崗筆試題

題目描述:

小v在公司負責遊戲運營,今天收到款申請新上架的遊戲“跳一跳”。爲了確保提供給廣大玩家朋友們的遊戲都是高品質的,按照運營流程小v必須對新遊戲進行全方位瞭解體驗和評估。這款遊戲的規則如下:
有n個盒子排成了一行,每個盒子上面有一個數字a[i],表示在該盒子上的人最多能向右移動a[i]個盒子(比如當前所在盒子上的數字是3,則表示可以一次向右前進1個盒子,2個盒子或者3個盒子)。
現在小v從左邊第一個盒子上開始體驗遊戲,請問最少需要移動幾次能到最後一個盒子上?

輸入描述:

輸入:2 2 3 0 4
表示現在有5個盒子,上面的數字分別是2, 2, 3, 0, 4。

輸出描述:
輸出: 2

小v有兩種跳法:

跳法1:盒子1--盒子2--盒子3--盒子4--盒子5,共3下

跳法2:盒子1--盒子3--盒子5,共2下

跳法2的步驟數量最少,所以輸出最少步數:2。

輸入:

2 2 3 0 4

輸出:

2

核心代碼:
 

int jump(int a[], int n) {
    int steps = 0;
    int start = 0;
    int end = 0;
    while(end < n - 1)
    {
        int max_pos = 0;
        for(int i = start; i <= end; ++i)
            max_pos = max(max_pos, i + a[i]);
        start = end + 1;
        end = max_pos;
        ++steps;
    }
    return steps;
}

題目描述:

今年7月份vivo迎來了新入職的大學生,現在需要爲每個新同事分配個工號。人力資源部同事小v設計了一個方法爲每個人進行排序並分配最終的工號,具體規則是:
將N (N<100000) 個人排成一排,從第1個人開始報數: 如果報數是M的倍數就出列,報到隊尾後則回到隊頭繼續報,直到所有人都出列;
最後按照出列順序爲每個人依次分配工號。請你使用自己擅長的編程語言幫助小v實現此方法。

輸入描述:

輸入2個正整數,空格分隔,第一個代表人數N,第二個代表M

輸出描述:

輸出一個int數組,每個數據表示原來在隊列中的位置用空格隔開,表示出列順序

輸入:

6 3

輸出:

3 6 4 2 5 1

這道題目就是簡單的約瑟夫環

核心代碼:

void loop(int n,int M)
{
    int a[n],m=0,number=0;
    int i,j;
    for(j=0;j<n;j++)
    {
        a[j]=(j+1);
    }
    int d = 0;
    for(i=0;i<n;i++)
    {
        if(a[i]>0)
        {
            m++;
            if(m==M)
            {
                if(d >= 1)
                    printf(" %d",a[i]);
                else
                    printf("%d", a[i]);
                d++;
                a[i]=0;
                m=0;
                number++;
                if(number==n)
                {
                    break;
                }
                
            }
        }
        if(i==(n-1))
        {
            i=-1;
        }
    }
    cout << endl;
}

題目描述:

小v最近在玩一款挖礦的遊戲, 該遊戲介紹如下:
1、每次可以挖到多個礦石,每個礦石的重量都不一樣,挖礦結束後需要通過一款平衡礦車運送下山; 
2、平衡礦車有左右2個車廂,中間只有1個車輪沿着導軌滑到山下,且礦車只有在2個車廂重量完全相等且礦石數量相差不超過1個的情況下才能成功運送礦石,否則在轉彎時可能出現側翻。

假設小v挖到了n (n<100) 個礦石,每個礦石重量不超過100,爲了確保一次性將n個礦石都運送出去,一旦礦車的車廂重量不一樣就需要購買配重砝碼。請問小v每次最少需要購買多少重量的砝碼呢? (假設車廂足夠放下這些礦石和砝碼,砝碼重量任選)

輸入描述:

輸入n個正整數表示每個礦石的重量

輸出描述:

輸出一個正整數表示最少需要購買的砝碼重量

輸入:

3 7 4 11 8 10

輸出:

1

說明:

小v可以將重量3,7和11的礦石放到左車廂,重量4,8和10放到右車廂,然後購買重量爲1的砝碼放到左車廂。

題解:其實可以轉換爲求n個數分成兩半,使絕對值差就小,我們可以轉化爲01揹包去做。

這個題目當時只過了差不多百分之八十,一直沒有搞懂原因,今天摘抄題目的時候才發現題目要求是礦石的數量最多相差爲1,哭唧唧,現在貼的是提交的代碼,正確的之後再改吧!!!!

代碼:

void loop(int n, int weight[])
{
    int Sum = 0, sum;
    int dp[10009];
    for(int i = 0; i < n; i++)
        Sum += weight[i];
    sum = Sum / 2;
    memset(dp, 0, sizeof(dp));
    for(int i = 0; i < n; i++)
        for(int v = sum; v >= weight[i]; v--)
            dp[v] = max(dp[v], dp[v - weight[i]] + weight[i]);
    Sum -= dp[sum];
   // cout << dp[sum] << endl;
   // cout << Sum << endl;
    if(Sum > dp[sum])
        cout << Sum - dp[sum] << endl;
    else
        cout << dp[sum] - Sum << endl;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章