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