1:平面最大點
P為給定的二維平面整數點集。定義 P 中某點x,如果x滿足 P 中任意點都不在 x 的右上方區域內(橫縱坐標都大於x),則稱其為“最大的”。求出所有“最大的”點的集合。(所有點的橫坐標和縱坐標都不重復, 坐標軸范圍在[0, 1e9) 內)
如下圖:實心點為滿足條件的點的集合。請實現代碼找到集合 P 中的所有 ”最大“ 點的集合並輸出。

輸入描述:
第一行輸入點集的個數 N, 接下來 N 行,每行兩個數字代表點的 X 軸和 Y 軸。 對於 50%的數據, 1 <= N <= 10000; 對於 100%的數據, 1 <= N <= 500000;
輸出描述:
輸出“最大的” 點集合, 按照 X 軸從小到大的方式輸出,每行兩個數字分別代表點的 X 軸和 Y軸。
輸入例子1:
5 1 2 5 3 4 6 7 5 9 0
輸出例子1:
4 6 7 5 9 0
思路:因為要尋找“最大點”,所以首先對所有點的y值進行排序,對於y值相同的點,x值也是有序的,y值最大的點,它必定是最大點,
此時,維護一個prex值,記錄現在已找出的“最大點”的集合中最大的x值,對於y值比上一個“最大點”小的點,其x值必定要比prex大,
才為“最大點”,若為“最大點”,把其加入“最大點”集合,同時,更新prex值。
import java.util.ArrayList; import java.util.Arrays; import java.util.Scanner; class Point implements Comparable<Point>{ int x; int y; public Point(int x, int y){ this.x = x; this.y = y; } @Override public int compareTo(Point o) { return y==o.y ? o.x - x : o.y - y; } } public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); sc.nextLine(); Point[] points = new Point[n]; for(int i = 0; i < n; i++) { points[i] = new Point(sc.nextInt(), sc.nextInt()); sc.nextLine(); } Arrays.sort(points); ArrayList<Point> max = new ArrayList<>(); max.add(points[0]); int prex = points[0].x; for(int i = 1; i < n; i++){ if(points[i].x > prex){ prex = points[i].x; max.add(points[i]); } } max.forEach((Point o) -> System.out.println(o.x + " " + o.y)); } }
這個算法沒通過牛客所有的樣例,出現了超時。
2:數組區間最大值
給定一個數組序列, 需要求選出一個區間, 使得該區間是所有區間中經過如下計算的值最大的一個:
區間中的最小數 * 區間所有數的和最后程序輸出經過計算后的最大值即可,不需要輸出具體的區間。如給定序列 [6 2 1]則根據上述公式, 可得到所有可以選定各個區間的計算值:
[6] = 6 * 6 = 36;
[2] = 2 * 2 = 4;
[1] = 1 * 1 = 1;
[6,2] = 2 * 8 = 16;
[2,1] = 1 * 3 = 3;
[6, 2, 1] = 1 * 9 = 9;
從上述計算可見選定區間 [6] ,計算值為 36, 則程序輸出為 36。
區間內的所有數字都在[0, 100]的范圍內;
輸入描述:
第一行輸入數組序列長度n,第二行輸入數組序列。 對於 50%的數據, 1 <= n <= 10000; 對於 100%的數據, 1 <= n <= 500000;
輸出描述:
輸出數組經過計算后的最大值。
輸入例子1:
3 6 2 1
輸出例子1:
36
思路:首先要找出區間,計算區間的最小值與區間所有數之和的乘積。而在找區間的過程中,把每一個數都當作子區間的最小值,從當前數
開始,尋找左右邊界,即找到比當前值還小的數時停止尋找,在找邊界的過程中,同時計算區間的和,最終比較得到能得到最大值的區間,並
輸出最大值。
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int[] num = new int[n]; sc.nextLine(); for(int i = 0; i < n; i++){ num[i] = sc.nextInt(); } int res = 0; for(int i = 0; i < n; i++){ int sum = num[i]; //左邊界 for(int j = i-1; j >= 0; j--){ if(num[j] >= num[i]){ sum += num[j]; }else{ break; } } //右邊界 for(int j = i+1; j < n; j++){ if(num[j] >= num[i]){ sum += num[j]; }else{ break; } } if(sum * num[i] > res){ res = sum * num[i]; } } System.out.println(res); } }
3:idea實現的時間點
產品經理(PM)有很多好的idea,而這些idea需要程序員實現。現在有N個PM,在某個時間會想出一個 idea,每個 idea 有提出時間、所需時間和優先等級。對於一個PM來說,最想實現的idea首先考慮優先等級高的,相同的情況下優先所需時間最小的,還相同的情況下選擇最早想出的,沒有 PM 會在同一時刻提出兩個 idea。
同時有M個程序員,每個程序員空閑的時候就會查看每個PM尚未執行並且最想完成的一個idea,然后從中挑選出所需時間最小的一個idea獨立實現,如果所需時間相同則選擇PM序號最小的。直到完成了idea才會重復上述操作。如果有多個同時處於空閑狀態的程序員,那么他們會依次進行查看idea的操作。
求每個idea實現的時間。
輸入第一行三個數N、M、P,分別表示有N個PM,M個程序員,P個idea。隨后有P行,每行有4個數字,分別是PM序號、提出時間、優先等級和所需時間。輸出P行,分別表示每個idea實現的時間點。
輸入描述:
輸入第一行三個數N、M、P,分別表示有N個PM,M個程序員,P個idea。隨后有P行,每行有4個數字,分別是PM序號、提出時間、優先等級和所需時間。全部數據范圍 [1, 3000]。
輸出描述:
輸出P行,分別表示每個idea實現的時間點。
輸入例子1:
2 2 5 1 1 1 2 1 2 1 1 1 3 2 2 2 1 1 2 2 3 5 5
輸出例子1:
3 4 5 3 9
思路:
使用優先級隊列ideaQueue存儲每個pm所想要完成的idea,依照idea的提交時間進行排序,Idea mostDesiredIdea(int time)返回的是時間time時,當前pm最想完成的idea,在這個函數中,需要再構建一個優先級隊列ideaQueue2,排序原則就是優先級最高,所需時間最小,最早提出,把ideaQueue中所有提交時間小於time的idea入隊,mostDesiredIdea的求法就是,若ideaQueue2不為空,取隊頭元素,若為空則取ideaQueue的對頭元素,即提交時間最早的idea(目前的time<這個idea的提交時間),若ideaQueue2取了隊頭元素還不為空,把里邊的元素重新放入隊列ideaQueue中。
Idea selectIdea(PM[] pms, int time)的功能是從所有pm想要完成的idea中,挑選出一個idea,程序員進行執行,構建一個優先級隊列ideaQueue,排序原則就是所需時間最小,pm序號最小,需要注意,有可能當前的時間time都小於ideaQueue中idea的提交時間,這時,ideaqueue中的排序原則就需要按照提交時間進行排序,即當時間到達提交最早的idea的時間時,執行該idea。取出ideaQueue中的隊頭元素時,若還不為空,把剩下的元素插入到pm的ideaQueue中。
計算idea的endTime,取最大值的緣故是考慮到當前時間還沒到idea的提交時間,而該idea必定是時間到達其提交時間時立馬執行的idea,所以取提交時間postTime和程序員執行開始時間的最大值,再加上該idea所需花費的時間costTime,最后更新程序員的nextWorkTime,並把程序員再插入到程序員的優先隊列中,程序員的優先隊列programmerQueue的排序原則為,nextWorkTime越小。
idea.endTime = Integer.max(idea.postTime, programmer.nextWorkTime) + idea.costTime;
programmer.nextWorkTime = idea.endTime;
programmerQueue.offer(programmer);
代碼思想主要來自 https://blog.csdn.net/qq_23666815/article/details/79182805
import java.util.*; public class Main { static class Idea{ int pm; int postTime; int prio; int costTime; int endTime; public Idea(int pm, int postTime, int prio, int costTime){ this.pm = pm; this.postTime = postTime; this.prio = prio; this.costTime = costTime; } } static class PM { PriorityQueue<Idea> ideaQueue = new PriorityQueue<>(Comparator.comparingInt(x -> x.postTime)); //當前time時間下,這個PM最想完成的idea Idea mostDesiredIdea(int time){ PriorityQueue<Idea> ideaQueue2 = new PriorityQueue<>((i1, i2) -> { if(i1.prio != i2.prio) return i2.prio - i1.prio; else if(i1.costTime != i2.costTime) return i1.costTime - i2.costTime; else return i1.postTime - i2.postTime; }); while (ideaQueue.peek() != null && ideaQueue.peek().postTime <= time){ ideaQueue2.offer(ideaQueue.poll()); } Idea mostDesiredIdea = (ideaQueue2.isEmpty()) ? ideaQueue.poll() : ideaQueue2.poll(); while (!ideaQueue2.isEmpty()){ ideaQueue.offer(ideaQueue2.poll()); } return mostDesiredIdea; } } static class Programmer{ int nextWorkTime;//下次可以工作的時間 public Programmer(int nextWorkTime){ this.nextWorkTime = nextWorkTime; } } //從多個PM最想完成的idea中,選擇一個PM想要完成的idea private static Idea selectIdea(PM[] pms, int time){ PriorityQueue<Idea> ideaQueue = new PriorityQueue<>((i1, i2) -> { //return i1.costTime == i2.costTime ? i1.pm - i2.pm : i1.costTime - i2.costTime; if(i1.postTime == i2.postTime || (i1.postTime <= time && i2.postTime <= time)){ if(i1.costTime != i2.costTime) return i1.costTime - i2.costTime; else return i1.pm - i2.pm; } if(i1.postTime > time && i2.postTime > time) return i1.postTime - i2.postTime; if(i1.postTime > time) return 1; if(i2.postTime > time) return -1; return 0; }); for(int i = 1; i < pms.length; i++){ Idea desiredIdea = pms[i].mostDesiredIdea(time); if(desiredIdea != null){ ideaQueue.offer(desiredIdea); } } Idea idea = ideaQueue.poll(); while (!ideaQueue.isEmpty()){ Idea tmp = ideaQueue.poll(); pms[tmp.pm].ideaQueue.offer(tmp); } return idea; } public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); //產品經理 int m = sc.nextInt();//程序員 int p = sc.nextInt();//任務數 List<Idea> ideas = new LinkedList<>(); while(p-- > 0){ ideas.add(new Idea(sc.nextInt(),sc.nextInt(),sc.nextInt(),sc.nextInt())); } PM[] pms = new PM[n+1]; for(int i = 1;i <= n; i++){ pms[i] = new PM(); } for(Idea idea : ideas){ pms[idea.pm].ideaQueue.offer(idea); } PriorityQueue<Programmer> programmerQueue = new PriorityQueue<>(Comparator.comparingInt(x -> x.nextWorkTime)); for(int i = 0; i < m; i++) programmerQueue.offer(new Programmer(0)); //int num = 0; while(true){ Programmer programmer = programmerQueue.poll(); Idea idea = selectIdea(pms, programmer.nextWorkTime); if(idea == null) break; idea.endTime = Integer.max(idea.postTime, programmer.nextWorkTime) + idea.costTime; programmer.nextWorkTime = idea.endTime; programmerQueue.offer(programmer); } for(Idea idea : ideas){ System.out.println(idea.endTime); } } }