写一个方法:
有五个数,都带一位小数(如果是整数则是XX.0),将他们相加,如果合计不是100的话则将这五个数只比较小数点后面的数,进行排序,之后将最大的数+0.1,然后五个数相加,如果不是100,则将第二大的数+0.1,然后再相加,如果不是100再将第三个大的数+0.1,以此类推,直到五个数的合为100或者第五个数+0.1为止,然后返回五个数的结果比如我只举个排序的例子
18.9和20.4比较则认为是18.9大(比较小数点后面的数),则将18.9+1
大概就是这样的据说难住好几个人哈哈
其实我也没想出来有人给个算法么
有五个数,都带一位小数(如果是整数则是XX.0),将他们相加,如果合计不是100的话则将这五个数只比较小数点后面的数,进行排序,之后将最大的数+0.1,然后五个数相加,如果不是100,则将第二大的数+0.1,然后再相加,如果不是100再将第三个大的数+0.1,以此类推,直到五个数的合为100或者第五个数+0.1为止,然后返回五个数的结果比如我只举个排序的例子
18.9和20.4比较则认为是18.9大(比较小数点后面的数),则将18.9+1
大概就是这样的据说难住好几个人哈哈
其实我也没想出来有人给个算法么
for (int i = 0; i<5; i++) {
if (sum(nums) == 100.0) break;
sort(nums); // 这个排序函数的比对规则只能根据小数点后一位来实现;
nums[i]+=0.1;
}
println(nums);这里面存在风险的是if (sum(nums) == 100.0),如果不行的话,就要写成: if (abs( sum(nums) - 100) < 0.0001)
// TODO Auto-generated method stub
double [] nums=new double[] {12.3,13.1,14.5,16.4,16.8};
double [] result= count(nums);
for(double temp:result){
System.out.println(temp);
}
}
static double[] count(double[] oldNums){
double sum=0;
int count=0;
double[] nums=oldNums;
for(int i=0;i<oldNums.length;i++){
sum+=oldNums[i];
}
if(sum!=100){
//count=1;
while(sum<=100){
nums=sort(nums,count);
count++;
sum=0;
for(int i=0;i<nums.length;i++){
sum+=nums[i];
if(sum>100){
System.out.println(sum+"sum已经大于0了");
break;
}
}
}
}
return nums;
}
static double[] sort(double [] oldNums,int times){
double[] newNums=new double[5];
//对原始数组进行冒泡排序
for(int i=0;i<oldNums.length-1;i++){
for(int j=0;j<oldNums.length-1-i;j++){
if((oldNums[j]%1)<(oldNums[j+1]%1)){
double temp=0;
temp=oldNums[j];
oldNums[j]=oldNums[j+1];
oldNums[j+1]=temp;
}
}
}
oldNums[times%3]+=0.1;
newNums=oldNums;
return newNums;
}
做得有点复杂,double类型的数会有精度损失,所以很难等于100 ,我是菜鸟...
补充说明下1.加过0.1得数就不在进行比较了,也就是说5个数第一个数加了0.1,那么下次比较只是剩下的四个数比较
2.如果有大小相同的小数,则只将其中一个数(哪个都行)+0.1,然后这个加过0.1得数从比较行列里去掉
3.最后合计为100的时候,也就是说处理做完了,要返回的时候,返回的五个数的顺序需要和进来时一样,比如说进来时是{A,B,C,D,E},进行排序处理之后是{B,C,E,A,D},这样返回去是错的,需要将它再变回{A,B,C,D,E}如果能算出这个题,那恭喜你离进大公司进了一步(不是能进啊,还有别的题)
还是很容易实现啊,如果不考虑所谓高性能的话:double[] nums = {}; // 原始数据
int[] excludes = {-1,-1,-1,-1,-1}; // 用于记录不进行最大值比较的数组下标
for (int i = 0; i<nums.lenght; i++) {
if (sum(nums) == 100.0) break;
int p = getMaxIndex(nums, excludes); // 获取除去excludes所包含数组下标以外的数的最大值(小数点后一位)
excludes[i] = p; // 记录这个下标,下次就不参与了
nums[p]+=0.1;
}
println(nums);
getMaxIndex里面也很简单:
public int getMaxIndex(double[] nums, int[] excludes) {
int max = Integer.MIN;
int maxPos = -1;
for (int i = 0; i<nums.lenght; i++) {
先检查excludes里面有没有i,有就直接next;
再检查nums[i]>max,如果大于就:max=nums[i];maxPos = i;
}
return i;
}
比如得到权重 [4,2,1,3,0] 而 n=2时,对权重>2的数+0.1
输出 a1+0.1, a2, a3, a4+0.1, a5。
变相排序,但不必移位。
double[] a = {1.7, 20.4, 2.0, 36.6, 39.1};
do_BT_problem(a);
for(double b:a)
System.out.print(String.format("%1$.1f ", b));
}private static double[] do_BT_problem(double[] a) {
double sum = 0.0f;
for(double item:a)
sum += item;
int[] order_nums = new int[5]; //存放5个浮点数的小数位,用于排序
for(int i=0; i<5; i++) {
order_nums[i] = (int)(a[i]*10) - ((int)a[i])*10;
}
int[] indexs = {0, 1, 2, 3, 4}; //索引数组,只对索引排序,原数组的数据保持不变
for(int i=4; i>0; i--) {
for(int j=0, temp; j<i; j++) {
if(order_nums[indexs[j]]<order_nums[indexs[j+1]]) {
temp = indexs[j];
indexs[j] = indexs[j+1];
indexs[j+1] = temp;
}
}
}
if(sum<99.95) { //根据算法来+0.1
for(int i=0; i<5 && Math.abs(100.0-sum)>0.05; i++) {
a[indexs[i]] += 0.1;
sum += 0.1;
}
}
return a;
}
2、相加,所得的和>100或者<=99.5,直接全部加0.1了输出
3、如果和<=100且>99.5,比如99.6,则用100-99.6=0.4,然后把排序后的数从大往小数4个,各加0.1了之后全部输出
第一个循环,取出最大值(小数位),最小值(小数位)的索引,并取得5个数的总和,之后可以计算出需要由大到小需要几个数加0.1.总共6种状况0~5个数加0.1。0和5就不说了。如果是1个,最大的索引已经取出。直接加;如果是两个,循环,不是已知的最大最小值索引中,最大的那个加0.1,同时第一个循环取得的最大值索引对应的加0.1;如果是3个,除最大最小外全+0.1,循环的同时,取得剩余3个的最小值索引。循环后其减0.1;如果是四个,只要不是第一次循环取得的最小值索引,全加0.1;
public class Test{
//获取小数点一位的0-20数(保证加起来小于100)
private static double getRandomFloat() {
double i = Math.random()*20;
//java.text.NumberFormat format=java.text.NumberFormat.getInstance();
//format.setMaximumFractionDigits(1);
double j = (double)(Math.round(i*10))/10.0;
//double j = Double.parseDouble(format.format(i));
System.out.println(j);
return j;
}
public static void sort(double[] data) {
double temp;
for(int i=1;i<data.length;i++){
for(int j=i;(j>0)&&(data[j]>data[j-1]);j--){
temp = data[j];
data[j] = data[j - 1];
data[j - 1] = temp;
}
}
}
public static void main(String[] args) {
//随机生成5个数
double [] ranArray = new double[5];
double sum = 0.0;
for (int i = 0; i < ranArray.length; i++) {
ranArray[i] = getRandomFloat();
sum += ranArray[i];
}
int index = 0;
while (sum < 100.0 && index < 5)
{
sort(ranArray);
ranArray[index] += 0.1;
ranArray[index] = (double)(Math.round(ranArray[index]*10))/10.0;
index++;
}
for (int i = 0; i < ranArray.length; i++) {
System.out.println(ranArray[i] + " ");
}
}
}
for (int i = 0; i<5; i++) {
if (sum(nums) == 100.0) break;
sort(nums); // 这个排序函数的比对规则只能根据小数点后一位来实现;
nums[i]+=0.1;
}
println(nums);
很好的标准
2、将total与100比较。total>=100,则返回。小于100,则得到差值num(如num=0.4)。(不清楚java的double与int计算是否要注意精度问题。)
3、将5个数的小数进行从大到小排序。
4、如果num*10<=5,则直接将前num*10的数组中的值直接加0.1输出,反之,前5个数每个数加0.1进行输出
这样不知行不行?,应该可行吧?
sort(num);//排序后的数组
sumResult = sum(num);//全部数想加
result = 100f - sumResult;
if(result >= 0.5) return num[4] + 0.1f;
if ... return ...
if ... return ...