1. 程式人生 > >騰訊2018秋招筆試真題(1)

騰訊2018秋招筆試真題(1)

騰訊2018秋招筆試真題

小Q的歌單

【題目描述】小 Q 有 X 首長度為 A 的不同的歌和 Y 首長度為 B 的不同的歌,現在小 Q 想用這些歌組成一個
總長度正好為 K 的歌單,每首歌最多隻能在歌單中出現一次,在不考慮歌單內歌曲的先後順序的情況下,
請問有多少種組成歌單的方法。
輸入描述:
每個輸入包含一個測試用例。
每個測試用例的第一行包含一個整數,表示歌單的總長度 K(1<=K<=1000)。
接下來的一行包含四個正整數,分別表示歌的第一種長度 A(A<=10)和數量 X(X<=100)以及歌的第二種長度
B(B<=10)和數量 Y(Y<=100)。保證 A 不等於 B。
輸出描述:
輸出一個整數,表示組成歌單的方法取模。因為答案可能會很大,輸出對 1000000007 取模的結果。
輸入示例:
5
2 3 3 3
輸出示例:
9

解題思路:
x首歌裡面取i首,每首歌長度為A
y首歌裡面取j首歌,每首歌長度為B
加起來長度為K
i*A + j*B = K
有多少種方式,可看成排列組合來做
類比(有一個盒子中裝有紅球x個,白球y個,取出紅球得A分,取出白球得B分,從中任意取使得得到的分數為K分,有多少種方法)
滿足條件
0 <= i <= x
j = (K-i*A)/B <= y
(K-i*A)%B = 0

import java.util.Scanner;

public class Main01 {
    public static void main(String[] args) {
        int
[][] c = new int[101][101];//組合排列 Scanner in = new Scanner(System.in); int K = in.nextInt(); //歌單總長度 int A = in.nextInt(); //第一種歌的長度 int x = in.nextInt(); //第一種歌的數量 int B = in.nextInt(); //第二種歌的長度 int y = in.nextInt(); //第二種歌的數量 //初始化陣列c 第一個引數是下標, 第二個引數是上標 c[0
][0] = 1; for(int i = 1; i < c.length; i++) { c[i][0] = 1; for(int j = 1; j < c[0].length; j++) { c[i][j] = (c[i - 1][j - 1] + c[i - 1][j]) % 1000000007; } } int res = 0; for(int i = 0; i <= x; i++) { //i首長度為A的歌 if(i * A <= K && (K - i * A) % B == 0 && (K - i * A) / B <= y) { res = (res + ((c[x][i] * c[y][(K-(i * A)) / B])) % 1000000007 ) % 1000000007; } } System.out.println(res); } }

安排機器

【題目描述】小 Q 的公司最近接到 m 個任務, 第 i 個任務需要 xi 的時間去完成, 難度等級為 yi。
小 Q 擁有 n 臺機器, 每臺機器最長工作時間 zi, 機器等級 wi。
對於一個任務,它只能交由一臺機器來完成, 如果安排給它的機器的最長工作時間小於任務需要的時間,
則不能完成,如果完成這個任務將獲得 200 * xi + 3 * yi 收益。
對於一臺機器,它一天只能完成一個任務, 如果它的機器等級小於安排給它的任務難度等級, 則不能完成。
小 Q 想在今天儘可能的去完成任務, 即完成的任務數量最大。如果有多種安排方案,小 Q 還想找到收益最大
的那個方案。小 Q 需要你來幫助他計算一下。
輸入描述:
輸入包括 N + M + 1 行,
輸入的第一行為兩個正整數 n 和 m(1 <= n, m <= 100000), 表示機器的數量和任務的數量。
接下來 n 行,每行兩個整數 zi 和 wi(0 < zi < 1000, 0 <= wi <= 100), 表示每臺機器的最大工作時間和
機器等級。
接下來的 m 行,每行兩個整數 xi 和 yi(0 < xi < 1000, 0 <= yi<= 100), 表示每個任務需要的完成時間和
任務的難度等級。
輸出描述:
輸出兩個整數, 分別表示最大能完成的任務數量和獲取的收益。
輸入示例:
1 2
100 3
100 2
100 1
輸出示例:
1 20006

解題思路:
對2個佇列分別進行排序
排序規則為:先按time從大到小排,再按level從大到小排(因為時間佔收益的比重比較大,所以優先time排序)
然後處理任務進行匹配
匹配規則為:選擇機器時間>=任務時間,機器優先順序與任務優先順序最接近的

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;

class Task implements Comparable {
    int time; //時間
    int level; //等級
    public Task(int time, int level) {
        super();
        this.time = time;
        this.level = level;
    }

    @Override
    public int compareTo(Object o) {
        Task t = (Task)o;
        if(this.time > t.time) {
            return -1;//返回-1,表示當前物件在前,即從大到小排序
        } else if(this.time < t.time) {
            return 1;
        } else {
            if(this.level > t.level) {
                return -1;
            } else {
                return 1;
            }
        }
    }

}

public class Main02 {
    public static void main(String[] args) {
        List<Task> machine = new ArrayList<Task>();
        List<Task> job = new ArrayList<Task>();
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        int m = in.nextInt();
        for(int i = 0; i < n; i++) {
            Task t = new Task(in.nextInt(), in.nextInt());
            machine.add(t);
        }
        for(int j = 0; j < m; j++) {
            Task t = new Task(in.nextInt(), in.nextInt());
            job.add(t);
        }
        Collections.sort(machine);
        Collections.sort(job);

        int count = 0;
        int sum = 0;
        int[] mark = new int[101];
        for(int i = 0, j = 0; i < m; i++) {//m項任務
            while(j < n && machine.get(j).time >= job.get(i).time) {
                //由於從大到小排序,所以如果machine.time比位於前面的job.time大,那也比後面的大,後面只需要比較優先順序
                mark[machine.get(j).level]++;
                j++;
            }
            for(int k = job.get(i).level; k <= 100; k++) {
                if(mark[k] != 0) {//mark[k]=1時表示優先順序為k的機器可以處理該任務
                    count++;
                    sum += 200 * job.get(i).time + 3 * job.get(i).level;
                    mark[k]--;
                    break;
                }
            }
        }
        System.out.println(count + " " + sum);
    }
}