第一个问题m台服务器包含属性。
是否支持编号、CPU内核数、内存、CPU体系结构和NP加速
根据资源分配请求,分配n台满足请求的服务器。 资源分配要求为CPU内核数( cpuCount )、内存( memSize )、CPU体系结构(=cpuArch )、是否支持图形(=supportNP )。
分配时,还指定了优先级级别的策略strategy。 政策如下:
策略1:CPU优先。 与分配请求最接近的CPU计数中,memSize次之。
战略2 :内存优先。 与分配请求最接近的memSize的cpuCount次之。输入
第1行服务器数m台
以下m行是m个服务器属性的数组
后续行动分配要求:最大分配数n、分配策略strategy、cpuCount、memSize、cpuArch、supportNP
需要注意的是,cpuArch使用9表示所有CPU体系结构都满足分配要求,而supportNP为2则表示满足分配要求,而不管是否支持NP卡。输出
先输出实际分配的数量,按照每个分配的服务器编号从小到大的顺序排列样例
输入:
2
0,2200,1,0
一,三,四百,二,一
2 2 3 300 3 2
输出:
0
思路
基于面向对象的思想,将服务器构建为类,属性中包含主要id、cpuCount、memSize。
为不同的分配策略创建两种类型的堆: CPU优先级和内存优先级。 将根据资源分配请求输入的服务添加到堆中,输出在输出堆中的sid之前将输出确定的结果。代码
import java.util.*; 公共类主0728 { staticpriorityqueueserverqueue; publicstaticvoidmain (字符串[ ] args ) scannersc=newscanner ) system.in ); int M=sc.nextInt (; sc.nextLine (; int[][] CPU=new int[M][5]; for(intI=0; i M; I ) { String[] str=sc.nextLine ().split ),); CPU [ I ] [0]=integer.parseint (str [0]; CPU [ I ] [1]=integer.parseint (str [1]; CPU [ I ] [2]=integer.parseint (str [2]; CPU [ I ] [3]=integer.parseint (str [3]; CPU [ I ] [4]=integer.parseint (str [4]; } int[] target=new int[6]; for(intI=0; i 6; I({target[I]=sc.nextint ); //制作最小堆,分为战略1和2制作。 if(target[1]==1) queue=newpriorityqueue((O1,o2 )-) if ) O1.CPUCNT==O2.CPUCNT ) if ) O1.memsize } eler } else { retur no1.CPU CNT-O2.CPU CNT; }; ); }elseif(target[1]==2) queue=newpriorityqueue((O1,o2 )-if ) O1.memsize==O2.memsize ) if ) O1.memsize }else{ return o1.memSize -
o2.memSize; } }); } //将符合规定的入堆 for(int i = 0; i < M; i++){ if(CPU[i][1] >= target[2] && CPU[i][2] >= target[3] && (target[4] == 9 || CPU[i][3] == target[4]) && (target[5] == 2 || CPU[i][4] == target[5])){ queue.add(new Server(CPU[i][0], CPU[i][1], CPU[i][2])); } } //合格的结果 int n = Math.min(queue.size(), target[0]); int[] res = new int[n]; for(int i = 0; i < n; i++){ res[i] = queue.poll().sid; } Arrays.sort(res); System.out.print(n); for(int i = 0; i < n; i++){ System.out.print(" " + res[i]); } } public static class Server{ public int sid; public int cpuCnt; public int memSize; public Server(int sid, int cpuCnt, int memSize){ this.sid = sid; this.cpuCnt = cpuCnt; this.memSize = memSize; } }} 第二题坦率的蛋挞服药,m个药方需要全部服用完才能治愈,但一天内不能同时服用超过n种药方。药方之间有依赖关系,二维数组[1,3],[2,3],[3,4]表示3必须在1、2之后服用,4必须在3之后服用。药方编号从1到m,有依赖关系的药方不能在同一天服用,不然有副作用。不存在药方循环依赖。
最短需要多少天服完药?
输入
总药方m
每天最大喝药数量n
依赖组数z
依赖项1
…
依赖项z
输出
最短天数
样例
输入:
8
2
6
2 1
3 1
4 2
1 5
6 7
7 8
输出:
4
解释:
第一天吃3、4号,第二天吃2、6号,第三天吃1、7号,第四天吃5、8号,最快需要4天。
思路
拓扑排序。用map存储依赖的指向关系,int数组存储被依赖数(入度)。
建立一个队列,把没有依赖点的节点放入队列。
在队列中还有顶点的条件下while循环,将弹出节点的依赖次数-1,如果为0,入队列。
for循环的次数即是吃药的次数,也就是循环多少次使队列为空。
代码
import java.util.*;public class Main08292 { public static void main(String[] args) { Scanner sc = new Scanner(System.in), int m = sc.nextInt(); int n = sc.nextInt(); int z = sc.nextInt(); int[][] input = new int[z][2]; //记录指向关系 Map<Integer, List<Integer>> map = new HashMap<>(); //记录被依赖数,入度数组 int[] count = new int[m]; for(int i = 0; i < z; i++){ input[i][0] = sc.nextInt(); input[i][1] = sc.nextInt(); int key = input[i][0]; int val = input[i][1]; count[val - 1]++; if(map.containsKey(key - 1)){ map.get(key - 1).add(val - 1); }else { List<Integer> list = new ArrayList<>(); list.add(val - 1); map.put(key - 1, list); } } int res = 0; Queue<Integer> queue = new LinkedList<>(); for (int i = 0; i < m; i++){ //没有依赖点的放入堆中 if(count[i] == 0) queue.add(i); } while(!queue.isEmpty()){ //每次取出的节点数 int min = Math.min(queue.size(), n); for(int i = 0; i < min; i++){ int t = queue.poll(); if(map.containsKey(t)){ List<Integer> l = map.get(t); for (int j = 0; j < l.size(); j++){ count[l.get(j)]--; if(count[l.get(j)] == 0) queue.add(l.get(j)); } } } res++; } System.out.println(res); }} 第三题同leetcode980
思路
回溯。
代码