2020春招百度笔试之发工资

发工资

n种货币,货币不可拆分, 每月发的工资>=员工工资,求最多发几月工资。
输入:

 3 51
 100 1
 50 4
 1 2

解释:3钟货币,员工工资51,下面三行对应,货币面额和数量
输出:
4
解释:
100
50 1
50 1
50 50
共最多发四个月工资

思路:贪心
1、先排序从大到小,处理>=工资的面额
2、开始贪心,每次贪<=need的面额,直到need大于所有的面额
3、从最小开始贪心
4、使用货币数量来控制while循环,用光货币数量退出循环
比如:三种货币,工资10,1/3/7元的面额各有三张。即

7 x 3
2 x 5
1 x 1

找比10 小或等的最接近10的面额为7 ,10 - 7 = 3,
找比3 小或等的最接近3的面额为2 , 3 - 2 = 1;
找比1 小或等的最接近3的面额为1,1-1 = 0;退出for循环;
此时

7 x 2
2 x 4
1 x 0

找比10 小或等的最接近10的面额为7 ,10 - 7 = 3,
找比3 小或等的最接近3的面额为2 , 3 - 2 = 1;
找比1 小或等的最接近3的面额没有,退出for循环;
此时只能从最小面额2贪心 1-2 <0退出循环。

 //处理货币面额大于need,从最小的开始遍历
            if (need > 0) {
                for (int j = n - 1; j >= strat; j--) {
                    if (a[j][1] > 0) {
                        need -= a[j][0];
                        a[j][1]--;
                        cnt--;
                        System.out.printf("\t" + a[j][0] + "\t");
                        if (need <= 0) {
                            ret++;
                            break;
                        }
                    }
                }
            }

import java.util.Arrays;
import java.util.Comparator;
import java.util.Scanner;

public class Main {
    //2 .发工资
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt(); //n种货币
        int salary = sc.nextInt(); //每月发的钱数
        int[][] a = new int[n][2];
        int cnt = 0;  //记录货币总数量
        for (int i = 0; i < n; i++) {
            int t0 = sc.nextInt();
            int t1 = sc.nextInt();
            a[i][0] = t0;  //货币面额
            a[i][1] = t1;  //货币数量
            cnt += a[i][1];
        }
        //面额排序从大到小
        Arrays.sort(a, new Comparator<int[]>() {
            @Override
            public int compare(int[] o1, int[] o2) {
                return o2[0] - o1[0];
            }
        });
        int ret = 0; //最多支付几个月工资
        int strat = 0;  //记录面额小于工资的起始下标
        //先处理大于工资面额的货币。
        for (int i = 0; i < n; i++) {
            if (a[i][0] >= salary) {
                ret += a[i][1];
                cnt -= a[i][1];
                System.out.printf("\t" + a[i][0] + "\t" + a[i][1]);
                a[i][1] = 0;
            } else {
                strat = i;  //
                break;
            }
        }
        //遍历面额小于工资的货币,直到用光所有货币,即货币数量=0
        while (cnt > 0) {
            System.out.println();
            int need = salary;
            //贪心,贪<=need的货币面额,知道货币面额都大于need
            for (int i = strat; i < n; i++) {
                int ti = i;
                if (a[i][1] > 0){
                    if (need < a[i][0])
                        continue;
                    else if (need == a[i][0]) {
                        ret++;
                        a[i][1]--;
                        need -= a[i][0];
                        cnt--;
                        System.out.printf("\t" + a[i][0] + "\t");
                        break;
                    } else if (need > a[i][0]) {
                        a[i][1]--;
                        cnt--;
                        need -= a[i][0];
                        System.out.printf("\t" + a[i][0] + "\t");
                        i = ti - 1;
                        continue;
                    }
                }
            }
            //处理货币面额大于need,从最小的开始遍历
            if (need > 0) {
                for (int j = n - 1; j >= strat; j--) {
                    if (a[j][1] > 0) {
                        need -= a[j][0];
                        a[j][1]--;
                        cnt--;
                        System.out.printf("\t" + a[j][0] + "\t");
                        if (need <= 0) {
                            ret++;
                            break;
                        }
                    }
                }
            }
        }
        System.out.println();
        System.out.println(ret);
    }
}

自测的用例:

3 10
 1 3
 2 3
 7 3
 5 51
 100 1
 55 4
 1 2
 2 10
 3 8

你可能感兴趣的:(笔试编程题)