爱情数字
题目
小王向小红表白,小红门口有一个大广告牌,小王想用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);
}
}