POJ 3299 Humidex Java题解

前言

读者们你们好! 接下来你们将看到我关于POJ 3299 Humidex这道题的理解。博主我是从这一题才正式开始学习算法的,所以耗费了很长时间(将近一天)才最终完成,过程中对于题目和Java编程的一些问题有所感悟,所以决定记录下来,以便后续的改进和反省,并将结果分享给大家。

题目

本道题来自北京大学的POJ系统,题号3299,题名Humidex。

链接: POJ3299

对于题目的理解

这道题本身不难,其要求就是:在Temperature, Dewpoint和Humidex这三个变量中,任意已知其中两个变量的前提下求出第三个变量,最后按统一格式输出,题目中已经详细给了计算公式:

humidex = temperature + h
h = (0.5555)× (e - 10.0)
e = 6.11 × exp [5417.7530 × ((1/273.16) - (1/(dewpoint+273.16)))]
where exp(x) is 2.718281828 raised to the exponent x.

从算法角度来说,这道题没有难度,在许多刷题推荐帖上也被列为水题之一,接下来我从一个第一次接触POJ的人的角度来讲讲要注意的事项:

  1. 对于题目的理解一定要准确,我第一次就是只看了题目一遍,然后就去看输入输出的范例了,结果写出来的代码就只能针对范例给的那一种情况,提交也老是被判WrongAnswer,后来又仔细看了一遍题目才知道是要在三个变量中给二求一的,所以大家看题目一定要仔细。
  2. 代码的输出一定要处理得和范例给的一摸一样,小数点,字母的顺序等都要完全一致,不然是不会被系统通过的。
  3. 以上是对小白所讲的注意事项,老生大可不必阅读。

代码

以下是博主第一次通过系统判断的代码,尚未做任何优化,仅此记录一下,大家可自行修改,博主后续也会再优化的。

注意事项

对于没有接触过ACM模式的人来说,写代码时最大的困难大概就是要处理多行输入的问题,博主一开始也在这块花了不少时间。

题目的输入输出范例

Sample Input:
T 30 D 15
T 30.0 D 25.0
E

Sample Output:
T 30.0 D 15.0 H 34.0
T 30.0 D 25.0 H 42.3

源代码

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class Main {
    private static final double EXP = 2.718281828;
	
	//已知humidex和dewpoint求temperature
    public static double sloveHD(double hex, double dep) {
        BigDecimal exp1 = new BigDecimal("1").divide(new BigDecimal("273.16"), 12, RoundingMode.HALF_UP).subtract(new BigDecimal("1").divide(new BigDecimal(Double.toString(dep)).add(new BigDecimal("273.16")), 12, RoundingMode.UP));
        BigDecimal exp2 = new BigDecimal("5417.7530").multiply(exp1);
        double e = 6.11 * Math.pow(EXP, exp2.setScale(12, RoundingMode.HALF_UP).doubleValue());
        double h = 0.5555 * (e - 10.0);
        String result = Double.toString(hex - h);
        BigDecimal tem = new BigDecimal(result).setScale(1, RoundingMode.HALF_UP);
        return tem.doubleValue();
    }

	//已知humidex和temperature求dewpoint
    public static double sloveHT(double hex, double tem) {
        double h = hex - tem;
        double e = h / 0.5555 + 10.0;
        double dep = -(Math.log(e / 6.11) / 5417.7530) * 273.16 * 273.16 / (273.16 * (Math.log(e / 6.11) / 5417.7530) - 1);
        BigDecimal result = new BigDecimal(dep).setScale(1, RoundingMode.HALF_UP);
        return result.doubleValue();


    }

	//已知dewpoint和temperature求humidex
    public static double sloveTD(double tem, double dep) {
        BigDecimal exp1 = new BigDecimal("1").divide(new BigDecimal("273.16"), 12, RoundingMode.HALF_UP).subtract(new BigDecimal("1").divide(new BigDecimal(Double.toString(dep)).add(new BigDecimal("273.16")), 12, RoundingMode.UP));
        BigDecimal exp2 = new BigDecimal("5417.7530").multiply(exp1);
        double e = 6.11 * Math.pow(EXP, exp2.setScale(3, RoundingMode.HALF_UP).doubleValue());
        double h = 0.5555 * (e - 10.0);
        String result = Double.toString(new BigDecimal(Double.toString(tem)).doubleValue() + h);
        BigDecimal hex = new BigDecimal(result).setScale(1, RoundingMode.HALF_UP);
        return hex.doubleValue();
    }

    public static void getHex(String inPut) {
        String[] in = inPut.trim().split(" ");
        String nameOne = in[0];
        BigDecimal argOne = new BigDecimal(in[1]).setScale(1, RoundingMode.HALF_UP);
        String nameSecond = in[2];
        BigDecimal argSecond = new BigDecimal(in[3]).setScale(1, RoundingMode.HALF_UP);
        double hex;
        double tem;
        double dep;
        if ("H".equals(nameOne)) {
            if ("D".equals(nameSecond)) {
                hex = argOne.doubleValue();
                dep = argSecond.doubleValue();
                tem = sloveHD(hex, dep);
                System.out.println("T" + " " + tem + " " + nameSecond + " " + argSecond + " " + nameOne + " " + argOne);

            } else if ("T".equals(nameSecond)) {
                hex = argOne.doubleValue();
                tem = argSecond.doubleValue();
                dep = sloveHT(hex, tem);
                System.out.println(nameSecond + " " + argSecond + " " + "D" + " " + dep + " " + nameOne + " " + argOne);

            }

        } else if ("T".equals(nameOne)) {
            if ("H".equals(nameSecond)) {
                tem = argOne.doubleValue();
                hex = argSecond.doubleValue();
                dep = sloveHT(hex, tem);
                System.out.println(nameOne + " " + argOne + " " + "D" + " " + dep + " " + nameSecond + " " + argSecond);

            } else if ("D".equals(nameSecond)) {
                tem = argOne.doubleValue();
                dep = argSecond.doubleValue();
                hex = sloveTD(tem, dep);
                System.out.println(nameOne + " " + argOne + " " + nameSecond + " " + argSecond + " " + "H" + " " + hex);

            }

        } else if ("D".equals(nameOne)) {
            if ("H".equals(nameSecond)) {
                dep = argOne.doubleValue();
                hex = argSecond.doubleValue();
                tem = sloveHD(hex, dep);
                System.out.println("T" + " " + tem + " " + nameOne + " " + argOne + " " + nameSecond + " " + argSecond);

            } else if ("T".equals(nameSecond)) {
                dep = argOne.doubleValue();
                tem = argSecond.doubleValue();
                hex = sloveTD(tem, dep);
                System.out.println(nameSecond + " " + argSecond + " " + nameOne + " " + argOne + " " + "H" + " " + hex);

            }

        }
    }

    public static void main(String[] args) {
        try {
        	//处理输入
            Scanner in = new Scanner(System.in);
            String str = "";
            List allInput = new ArrayList();
            while (!"E".equals(str)) {
                str = in.nextLine();
                allInput.add(str);
            }
            allInput.remove(allInput.size() - 1);
            for (Object item : allInput) {
                getHex((String) item);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

结果

耗时了将近一天,虽然题目简单,但是过程艰难,最后成功了,对于我这个小白来说,还是很开心的啊!
在这里插入图片描述

后记

后期博主还会对代码进行优化,欢迎大家指出不足,希望我们都能在算法这条路上走得更远,共勉!

问题

记录一些在写代码过程中遇到的问题:

  1. 使用new BigDecimal(double val)要极其注意,有可能产生不可预知的后果,相关帖子可以参考:链接
  2. 平常使用的JDK一般是JDK8,POJ使用的JDK5,大家在编写的时候要注意,特别是关于泛型的方面。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
POJ 3635 是一道比较经典的数学题目,主要考察了一些数学知识和算法。下面是这道题的 Java 解题思路和代码实现: 题目描述: 给定一个正整数N,求最小的正整数M,使得 N*M 的十进制表示中只包含数字0和1。 输入格式: 一个正整数N。 输出格式: 一个正整数M,表示满足条件的最小正整数M。 Java 代码实现: ```java import java.util.*; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); long n = sc.nextLong(); long res = 1; Queue<Long> queue = new LinkedList<>(); Set<Long> set = new HashSet<>(); queue.offer(1L); set.add(1L); while (!queue.isEmpty()) { long t = queue.poll(); if (t % n == 0) { res = t; break; } long a = (t * 10) % n; long b = (t * 10 + 1) % n; if (!set.contains(a)) { queue.offer(a); set.add(a); } if (!set.contains(b)) { queue.offer(b); set.add(b); } } System.out.println(res); } } ``` 思路解析: 这道题的解题思路比较巧妙,我们可以采用 BFS 算法来解决。我们可以从 1 开始进行 BFS,每次将当前的数乘以 10 或者乘以 10 再加上 1,得到两个新的数,然后判断这两个新的数是否是 n 的倍数,如果是,则找到了最小的满足条件的数,退出 BFS。如果不是,则将两个新的数加入队列,继续进行 BFS。需要注意的是,由于 N 可能非常大,所以我们需要使用 long 类型来存储数值,同时我们需要使用集合来避免重复计算。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Exticntion

跪谢大佬的赞助!祝您万事如意!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值