Hihocoder-元素魔法

题目名称:元素魔法
题目链接:元素魔法
描述

小Hi是一个大魔法师,会用好多好多的魔法。小Hi一直在追求最强的魔法,每天都不敢懈怠,因此,小Hi今天也在勤勉地练习着魔法。

小Hi使用的魔法都是伤害类型的魔法,每次使用魔法时,小Hi会使用一定量的魔力,将这些魔力转化为不同类型的元素,再将这些元素组合起来释放。

小Hi的魔法的威力和他使用的元素的比例有关,假设小Hi能操纵的元素种类为k种,第i种元素的伤害系数为wi,某次魔法使用了xi单位的第i种元素,则该次魔法的威力为 ∏xiwi (其中xi和wi都是正的实数)。

小Hi的魔力是有限的,假设某天小Hi拥有的魔力为a(a也是正实数)魔法单位,则当天他最多能转换出总量为a单位的元素,即Σxi = a0 ≤ a。

每天他的魔力会随着使用魔法而消耗,只有在午夜0点才能回复。

由于小Hi对魔法的威力有着可怕的偏执,所以他每天只会使用一次魔法,并且这一次魔法的威力一定是他当天可能用出的所有魔法中,威力最大的一种。

但是小Hi不是很擅长数学,他希望有人帮他算出某天的魔法练习中他能释放出的魔法的最大威力是多少。

输入

第一行是一个正整数k(1 ≤ k ≤ 105),表示小Hi能操纵的元素种数。

第二行是1个正实数a(0 < a ≤ 2 × 105),表示小Hi某天的魔力总量。

第三行是k个正实数,第i个正实数wi(1 < wi < 2)表示第i种元素的伤害系数。

所有输入的实数保证都精确到小数点后第四位。

输出

输出共两行。

第一行输出一个正实数,表示小Hi当天所能使出的威力最大的魔法的威力是多少,由于这个值可能很大也可能很小,请输出其对e(自然对数的底)取对数之后的结果。

第二行输出k个正实数,第i个正实数xi表示这个魔法中由xi单位的第i种元素混合而成,相邻的实数之间由空格隔开。

以上输出均四舍五入到小数点后第五位。

样例输入

5
56.2
1.7751 1.2748 1.5646 1.5052 1.7651

样例输出

19.13257
12.65227 9.08631 11.15190 10.72852 12.58099

解题思路

    一个数学问题,正如讨论中给出的结论一样,元素的伤害系数和该元素的单位量比例相同的时候,即伤害最大的时候,在这里会出现一个问题,按照该思路下来会发现只能通过一半的样例,在参考其他的答案后发现这个问题出现的原因是由于数值计算过程中存在的误差导致的,曾经在数值计算与方法这门课程中老师就讲到过要尽量减少计算过程中的复杂度,使得计算过程更加精确。

完整代码

import java.text.DecimalFormat;
import java.util.Scanner;

public class Main {

    public static void main(String[] args){
        DecimalFormat df=new DecimalFormat("0.00000");
        Scanner in=new Scanner(System.in);
        int n;
        double sum,totalW=0.0,maxPower=0.0;
        double[] x=new double[100010],w=new double[100010];
        n=in.nextInt();
        sum=in.nextDouble();
        for(int i=0;i<n;i++){
            w[i]=in.nextDouble();
            totalW+=w[i];
        }

        for(int i=0;i<n;i++){
            x[i]=w[i]/totalW*sum;
            maxPower +=w[i]*Math.log(x[i]);
        }

        System.out.println(df.format(maxPower)) ;
        for(int i=0;i<n-1;i++){
            System.out.print(df.format(x[i])+" ");
        }
        System.out.println(df.format(x[n-1]));
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值