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