字節跳動2018校招大數據方向(第一批)編程題


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

    }

}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM