Vivo筆試題


1. 服務器最大訪問人數

  動態規划方法

import java.io.*;
import java.util.*;

import static java.lang.Math.max;

/**
 * @author zzm
 * @data 2020/4/16 22:22
 * 小v是公司的運維工程師,現有一個有關應用程序部署的任務如下:
1、一台服務器的磁盤空間、內存是固定的,現在有N個應用程序要部署;
2、每個應用程序所需要的磁盤、內存不同,每個應用程序允許訪問的用戶數也不同,且同一個應用程序不能在一台服務器上部署多個。
對於一台服務器而言,如何組合部署應用程序能夠使得單台服務器允許訪問的用戶數最多?

輸入描述:
輸入包括三個參數,空格分隔,分別表示服務器的磁盤大小、內存大小,以及應用程序列表;
其中第三個參數即應用程序列表,表述方式為:多個應用程序信息之間用 '#' 分隔,每個應用程序的信息包括 ',' 
分隔的部署所需磁盤空間、內存、允許訪問的用戶量三個數字;比如 50,20,2000 表示部署該應用程序需要50G磁盤空間,20G內存,允許訪問的用戶數是2000

輸出描述:
單台服務器能承載的最大用戶數

輸入例子1:
15 10 5,1,1000#2,3,3000#5,2,15000#10,4,16000

輸出例子1:
31000
 */
public class VVservice {
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String inputStr = br.readLine();
        String[] input = inputStr.split(" ");
        int totalDisk = Integer.parseInt(input[0]);
        int totalMemory = Integer.parseInt(input[1]);
        List<Service> services = parseServices(input[2].split("#"));
        int output = solution(totalDisk, totalMemory, services);
        System.out.println(output);
    }

    private static int solution(int totalDisk, int totalMemory, List<Service> services) {

        // TODO Write your code here
        int[][][] dp = new int[services.size() + 1][totalDisk+1][totalMemory+1];
        for (int i = 1; i <= services.size(); i++) {
            Service service = services.get(i - 1);
            for (int j = 1; j <= totalDisk; j++) {
                for (int k = 1; k <= totalMemory; k++) {
                    if (service.getDisk() > j || service.getMemory() > k) dp[i][j][k] = dp[i - 1][j][k];
                    else dp[i][j][k] = max(dp[i - 1][j][k], dp[i - 1][j-service.getDisk()][k - service.getMemory()] + service.getusers());
                }
            }
        }
        return dp[services.size()][totalDisk][totalMemory];
    }

    private static List<Service> parseServices(String[] strArr) {
        if (strArr == null || strArr.length == 0) {
            return new ArrayList<Service>(0);
        }
        List<Service> services = new ArrayList<>(strArr.length);
        for (int i = 0; i < strArr.length; i++) {
            String[] serviceArr = strArr[i].split(",");
            int disk = Integer.parseInt(serviceArr[0]);
            int memory = Integer.parseInt(serviceArr[1]);
            int users = Integer.parseInt(serviceArr[2]);
            services.add(new Service(disk, memory, users));
        }
        return services;
    }

    static class Service {
        private int disk;

        private int memory;

        private int users;

        public Service(int disk, int memory, int users) {
            this.disk = disk;
            this.memory = memory;
            this.users = users;
        }

        public int getDisk() {
            return disk;
        }

        public void setDisk(int disk) {
            this.disk = disk;
        }

        public int getMemory() {
            return memory;
        }

        public void setMemory(int memory) {
            this.memory = memory;
        }

        public int getusers() {
            return users;
        }

        public void setusers(int users) {
            this.users = users;
        }
    }
}

 2. 拆禮盒

package Algorithm;

import java.io.*;

/**
 * @author zzm
 * @data 2020/4/16 23:12
 * 現給出一個字符串,並假定用一對圓括號( )表示一個禮品盒,0表示獎品,你能據此幫獲獎者算出最少要拆多少個禮品盒才能拿到獎品嗎?

輸入描述:
一行字符串,僅有'('、')'、'0' 組成,其中一對'(' ')'表示一個禮品盒,‘0’表示獎品;輸入的字符串一定是有效的,即'(' ')'一定是成對出現的。

輸出描述:
輸出結果為一個數字,表示小v要拆的最少禮品盒數量

輸入例子1:
(()(()((()(0)))))

輸出例子1:
5
 */
public class VVpackagenum {

    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String inputStr = br.readLine();
        int output = solution(inputStr);
        System.out.println(output);
    }

    private static int solution(String str) {

        // TODO Write your code here
        int res = 0;
        for (char c : str.toCharArray()) {
            if(c=='0') return res;
            else if(c==')') res--;
            else res++;
        }
        return res;
    }
}

 3. 尋找滿足條件的正整數

import org.junit.Test;

import java.util.ArrayList;
import java.util.Collections;

/**
 * @author zzm
 * @data 2020/4/18 22:08
 * 現給定任意正整數 n,請尋找並輸出最小的正整數 m(m>9),使得 m 的各位(個位、十位、百位 ... ...)之乘積等於n,若不存在則輸出 -1。
 * 輸入例子1:36     輸出例子1:49
 * 輸入例子2:100       輸出例子2:455
 */
public class VVfindMinM {

    public int solution(int n) {
        // write code here
        if (n == 1) return 1;
        ArrayList<Integer> list = new ArrayList<>();
        while (n > 1) {
            int i;
            for (i = 9; i > 1; i--) {
                if (n % i == 0) {
                    list.add(i);
                    n = n / i;
                    break;
                }
            }
            if (i == 1) break;
        }
        if (n > 1) return -1;
        Collections.sort(list);
        StringBuilder str = new StringBuilder();
        list.forEach(a -> str.append(a));
        return Integer.parseInt(str.toString());
    }

    @Test
    public void test(){
        System.out.println(solution(1024));
    }
}

4. 計算生產的手機數量

/**
 * @author zzm
 * @data 2020/4/18 22:27
 * 在vivo產線上,每位職工隨着對手機加工流程認識的熟悉和經驗的增加,日產量也會不斷攀升。
 * 假設第一天量產1台,接下來2天(即第二、三天)每天量產2件,接下來3天(即第四、五、六天)每天量產3件 ... ...
 * 以此類推,請編程計算出第n天總共可以量產的手機數量。
 */
public class VVtotleproduct {
    public int solution(int n) {
        // write code here
        int day = 1, product = 1;
        int res = 0;
        for (int i = 0; i < n; i++) {
            res += product;
            if (--day == 0) day = ++product;
        }
        return res;
    }

    @Test
    public void test(){
        System.out.println(solution(11));
    }
}

 5. 手機解鎖問題

int[][] pathThrough = new int[10][10];    pathThrough[i][j] 代表從i到j需要經過的點(即i到j成功的前提是 pathThrough[i][j] 已經用過了)
boolean[] used = new boolean[10];   used[i] 代表第i個鍵已被按下,used[0]=true(任意普通連接如1-2,1-8 中間不依賴其他已經被按下的鍵,pathThrough為0,即默認0被按下)
/**
 * @author zzm
 * @data 2020/4/18 21:01
 * 現有一個 3x3 規格的 Android 智能手機鎖屏程序和兩個正整數 m 和 n ,請計算出使用最少m 個鍵和最多 n個鍵可以解鎖該屏幕的所有有效模式總數。
 * 其中有效模式是指:
 * 1、每個模式必須連接至少m個鍵和最多n個鍵;
 * 2、所有的鍵都必須是不同的;
 * 3、如果在模式中連接兩個連續鍵的行通過任何其他鍵,則其他鍵必須在模式中選擇,不允許跳過非選擇鍵(如圖);
 * 4、順序相關,單鍵有效(這里可能跟部分手機不同)。
 * 輸入:m,n
 * 代表允許解鎖的最少m個鍵和最多n個鍵
 * 輸出:
 * 滿足m和n個鍵數的所有有效模式的總數
 */
public class VVunlock {
    /**
     * 實現方案
     *
     * @param m int整型 最少m個鍵
     * @param n int整型 最多n個鍵
     * @return int整型
     */

    int[][] pathThrough = new int[10][10];
    boolean[] used = new boolean[10];

    public int solution(int m, int n) {
        // write code here
        if (m > n || n < 0) return 0;
        m = Math.max(1, m);
        n = Math.min(9, n);

        pathThrough[1][3] = pathThrough[3][1] = 2;
        pathThrough[1][7] = pathThrough[7][1] = 4;
        pathThrough[1][9] = pathThrough[9][1] = 5;
        pathThrough[2][8] = pathThrough[8][2] = 5;
        pathThrough[3][9] = pathThrough[9][3] = 6;
        pathThrough[3][7] = pathThrough[7][3] = 5;
        pathThrough[4][6] = pathThrough[6][4] = 5;
        pathThrough[7][9] = pathThrough[9][7] = 8;

        used[0] = true;
        int res = 0;

        for (int i = m; i <= n; i++) {
            res += 4 * dfs(1, 1, i) + 4 * dfs(2, 1, i) + dfs(5, 1, i);
        }
        // 1 3 7 9 相似,2 4 6 8相似, 5 單獨
        return res;
    }

    private int dfs(int start, int len, int target) {
        used[start] = true;
        if (len == target) {
            used[start] = false;
            return 1;
        }
        int count = 0;
        for (int i = 1; i <= 9; i++) {
            if (!used[i] && used[pathThrough[start][i]]) {
                count += dfs(i, len + 1, target);
            }
        }
        used[start] = false;
        return count;
    }


    @Test
    public void test() {
        System.out.println(solution(1, 2));
    }

}

 

 
 
       


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM