蘑菇街2016暑期实习笔试编程题

爱情数字

题目

小王向小红表白,小红门口有一个大广告牌,小王想用v升油漆在广告牌是写下一个爱情数字,数字的值越大,表白成功的几率越高。小王知道小红不喜欢0这个数字,所以不会写这个数字。每个数字都有需要使用的油漆数量,求小王能写出的最大的数字。

输入:

5
5 4 3 2 1 2 3 4 5

输出:

55555

思路:

使用贪心算法。首先对每个数字按照需要使用的油漆数量(weight)、以及数字大小(value)进行双快速排序。从排好序的数组中选择第一个数字,用总油漆数v除以该数的weight可以得出最后的位数k。再用v对第一个数字的weight进行取余remainder,如果结果为0则将k个第一个数字加入arraylist即为最后结果。如果不为0,则将该remainder(diff0)加上第一个数字的weight得到一个值diff1,按照排序后队列的顺序寻找weight小于diff1且value最大的值。将该值加入到arralist首位,相当于替换了原来的第一个数字。此时得到diff2 = diff1 - weight2,再继续向后移位替换(和前面步骤一样)。直到diff等于0位置。

代码:

import java.util.*;


public class Main {

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while(sc.hasNext()){
            int v = sc.nextInt();
            int[][] weight = new int[2][10];
            for(int i = 1; i < 10; i++ ){
                weight[0][i] = sc.nextInt();
                weight[1][i] = i;
            }
            qsort(weight, 1, 9); //对原二维数组进行双快速排序
            ArrayList<Integer> res = new ArrayList<Integer>();
            int k = v/weight[0][1];
            int diff = v%weight[0][1];
            while(diff != 0 && res.size() < k){
                diff += weight[0][1];
                int max = weight[1][1];
                int min = weight[0][1];
                for(int i = 2; i < 9; i++){
                    if(weight[0][i] <= diff && weight[1][i] > max){
                        max = weight[1][i];
                        min = weight[0][i];
                    }
                }
                diff = diff - min;
                res.add(max);               
            }
            int resSize = res.size();
            for(int i = 0; i < k - resSize; i++){
                res.add(weight[1][1]);
            }
            for(int i = 0; i < res.size(); i++){
                System.out.print(res.get(i));
            }
            System.out.println();
        }
    }
    public static void qsort(int[][] weight, int left, int right){ 
        if(left >= right)
            return;  //记得要判断退出条件
        int[] key = new int[2];
        int start = left;
        int end = right;
        key[0] = weight[0][left];
        key[1] = weight[1][left];
        while(left < right){
            while((left < right) && ( weight[0][right] > key[0] || 
                     (weight[0][right] == key[0] && weight[1][right] < key[1]))) //双快速排序的重点,第二维度大数在前,所以用小于号
                right --;
            weight[0][left] = weight[0][right];
            weight[1][left] = weight[1][right];
            while((left < right) && ( weight[0][left] < key[0] || 
                     (weight[0][left] == key[0] && weight[1][left] > key[1])))
                    left ++;
            weight[0][right] = weight[0][left];
            weight[1][right] = weight[1][left];
        }
        weight[0][left] = key[0];
        weight[1][left] = key[1];
        qsort(weight, start, left-1); //递归直接到left - 1即可
        qsort(weight, left+1, end);
    }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值