目录

hdoj刷题六(java):2050-2059

向同学了解到第11页后半段的题才有意思,于是先从 P2050 开始刷了,同时为了保持索引的有序性,名字也先取「六」了,「三四五」先空缺着。

Problem - 2050 折线分割平面

Problem - 2051 Bitset

这题为典型的10进制转二进制,不断取余2再除2就行。但是这样的数位是反的,所以我有两种思路将其弄正:

  • 一种是弄个数组反向输出,数组大小为log2(N+1)向上取整,向上取整有点东西的,一开始我表达式就写错了。并且学到了 java 的 log2n方式:

在java中求log2N,首先要弄明白一个初中学到的公式log2N=logeN/loge2,logeN代表以e为底的N的对数,loge2代表以e为底的2的对数. 在java.lang.math类中的log(double a)代表以e为底的a的对数,因此log2N在Java中的表示为: log((double)N)/log((double)2)

所以实际计算数组长度的时候代码如下:

int len = (int) Math.ceil((Math.log((double)(num+1))/Math.log((double)2)));

下面是完整代码:一遍过!

import java.util.Scanner;

/**
 * @author lhp
 * @description TODO
 * @date 2021/3/12 23:57
 */
public class P2051 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()){
            int num = sc.nextInt();
            ten2Two(num);
            System.out.println();
        }
    }

    private static void ten2Two(int num){
        int len = (int) Math.ceil((Math.log((double)(num+1))/Math.log((double)2)));
//        System.out.println("len:" + len);
        int[] numTwo = new int[len];
        int i = 0;
        while (num > 0){
            numTwo[i] = num % 2;
            num /= 2;
            i++;
        }
        for (int j=len-1; j>=0; j--){
            System.out.print(numTwo[j]);
        }
    }
}
  • 还有一种我想试试递归输出,先计算再输出,递归可能不占优,但是一直对递归的思想理解不透彻,想试试

没想到一下子就写出来了!果然凌晨是敲代码的最佳时机!奖励自己一片面包,长胖!

思路是这样的,既然最先算出来的最后输出,那么其实和树的后序遍历很像:先递归下去,返回到根节点的时候再输出,即,先把 num/2 传下去算着,等算完了再把 num%2 输出,递归退出判断是什么呢?当然是和上面那个方法的 while 退出判断一样啦,为0就退出。

以下是递归实现的函数部分:

private static void  ten2Two2(int num){
        if (num == 0){
            return;
        }
        else {
            ten2Two2(num/2);
            System.out.print(num%2);
        }
    }

Problem - 2052 Picture

画图狂喜,想起了以前大一的时候写打字游戏和贪食蛇。

这题主要是细节问题,注意 n>0m>0,其中 n 是宽度,即列数。以及每两个长方形之间有个空行。

因为输出太多,我嫌 java 的输出太长,抖了个机灵重新封装了一下哈哈哈,体验倍增!

(目前这题一直提示表达错误)

import java.util.Scanner;

/**
 * @author lhp
 * @description TODO
 * @date 2021/3/14 19:50
 */
public class P2052 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n, m;
        while (sc.hasNext()){
            n = sc.nextInt();
            m = sc.nextInt();
            //打印首行
            pr('+');
            for (int i=0; i<n; i++){
                pr('-');
            }
            pr('+');
            pr('\n');
            //打印中间部分
            for (int j=0; j<m; j++){
                pr('|');
                for (int k=0; k<n; k++){
                    pr(' ');
                }
                pr("|\n");
            }
            //打印尾行,和首行一样
            pr('+');
            for (int i=0; i<n; i++){
                pr('-');
            }
            pr('+');
            //注意每两个长方形之间有个空白行
            pr("\n\n");
        }
    }

    static void pr(Object o){
        System.out.print(o);
    }
}

Problem - 2053 Switch Game

判断第 n 个灯的状态,只要看 1 - n 中,有几个数能整除就行,用取余操作

import java.util.Scanner;

/**
 * @author lhp
 * @description TODO
 * @date 2021/3/14 20:22
 */
public class P2053 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n;
        while (sc.hasNext()){
            boolean open = false;
            n = sc.nextInt();
            for (int i=1; i<=n; i++){
                if (n%i == 0){
                    open = !open;
                }
            }
            System.out.println(open ? 1 : 0);
        }
    }
}

Problem - 2054 A == B ?

本来以为是水题,后来觉得没这么简单,然后用 Doubleeuqal函数,还是错。后面百度了一下,他们是用字符串,把后面的.00000000去掉,所以我猜,测试样例应该特别大。奇怪,我用new BigDecimal(sc.next()) 测试,还是通不过。下面是字符串解法:

还是有很多细节的,比如要考虑是否为小数,遍历顺序,以及是否要变小数为整数,详见代码:

import java.math.BigDecimal;
import java.util.Scanner;

/**
 * @author lhp
 * @description TODO
 * @date 2021/3/14 20:31
 */
public class P2054 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String m, n;
        while (sc.hasNext()){
            m = sc.next();
            n = sc.next();
            m = trim(m);
            n = trim(n);
            if (m.equals(n)){
                System.out.println("YES");
            }
            else {
                System.out.println("NO");
            }
        }
    }

    private static String trim(String s){
        //如果没有小数点就直接返回
        if (!s.contains(".")){
            return s;
        }
        //下面是有小数点的情况,从右往左,记录第一个非0的位置
        int len = s.length();
        int j = len - 1;
        for (; j>=0; j--){
            if (s.charAt(j) != '0'){
                break;
            }
        }
        //还要考虑小数点也要抹去的情况
        if (s.charAt(j) == '.'){
            return s.substring(0, j);
        }
        else {
            return s.substring(0, j+1);
        }
    }
}

Problem - 2055 An easy problem

这题对我来说最难的反而是输入,nextInt() 后需要多写一个 nextLine() 把回车吃掉,我猜 nextInt() 没有处理回车,然后 nextLine() 在第一个回车处终止,导致第一行数字后面的换行会消耗一个 nextLine()

import java.util.Scanner;

/**
 * @author lhp
 * @description TODO
 * @date 2021/3/14 21:07
 */
public class P2055 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        //需要把回车读了
        sc.nextLine();
        for (int i=0; i<n; i++){
            //java没有nextCharacter(),只能以字符串的形式读取
            String inputStr = sc.nextLine();
            //x只有一位
            char x = inputStr.charAt(0);
            //x是从下标为2到len-1部分
            int y = Integer.parseInt(inputStr.substring(2, inputStr.length()));
            System.out.println(y + f(x));
        }
    }

    private static int f(char ch){
        if (ch>='a' && ch<='z'){
            return -(ch - 'a' + 1);
        }
        //为了可阅读性,还是用else if吧
        else if (ch>='A' && ch<='Z'){
            return ch - 'A' + 1;
        }
        else {
            return 0;
        }
    }
}

Problem - 2056 Rectangles

Problem - 2057 A + B Again

Problem - 2058 The sum problem

Problem - 2059 龟兔赛跑