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)); } }