java算法练习04.14-04.15


依据大佬建议的 刷题步骤(杭电oj题目)
想偷个懒,有几题遇到基本没有遇到什么问题,就把答案一发;遇到问题的就和大家聊聊。

HD2003

linkOJ

  • @description
  • 求实数的绝对值。
  • Input
  • 输入数据有多组,每组占一行,每行包含一个实数。
  • Output
  • 对于每组输入数据,输出它的绝对值,要求每组数据输出一行,结果保留两位小数。
  • Sample Input
  • 123
  • -234.00
  • Sample Output
  • 123.00
  • 234.00
全代码
import java.text.DecimalFormat;
import java.util.Scanner;
public class Main {
   public static void main(String[] args) {
       Scanner scanner = new Scanner(System.in);
       double n;
       double result;
       while (scanner.hasNextDouble()) {
           n = scanner.nextDouble();
           if(n>=0) {
               result = n;
           } else {
               result = -n;
           }
           DecimalFormat format = new DecimalFormat("#.00");
           System.out.println(format.format(result));
       }
   }
}

HD2004

linkOJ

  • @description
  • 输入一个百分制的成绩t,将其转换成对应的等级,具体转换规则如下:
  • 90~100为A;
  • 80~89为B;
  • 70~79为C;
  • 60~69为D;
  • 0~59为E;
  • Input
  • 输入数据有多组,每组占一行,由一个整数组成。
  • Output
  • 对于每组输入数据,输出一行。如果输入数据不在0~100范围内,请输出一行:“Score is error!”。
  • Sample Input
  • 56
  • 67
  • 100
  • 123
  • Sample Output
  • E
  • D
  • A
  • Score is error!
全代码
import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n;
        while (sc.hasNextInt()) {
            n = sc.nextInt();
            if(n<0 || n>100) {
                out("Score is error!");
            } else {
                if(n <= 59) {
                    out("E");
                } else if(n<=69) {
                   out("D");
                } else if(n<=79) {
                    out("C");
                } else if(n<=89) {
                    out("B");
                } else {
                    out("A");
                }
            }
        }
    }

    public static void out(String str) {
        System.out.println(str);
    }
}

HD2005

linkOJ

  • @description
  • 给定一个日期,输出这个日期是该年的第几天。
  • @Input
  • 输入数据有多组,每组占一行,数据格式为YYYY/MM/DD组成,具体参见sample input ,
  • 另外,可以向你确保所有的输入数据是合法的。
  • @Output
  • 对于每组输入数据,输出一行,表示该日期是该年的第几天。
  • Sample Input
  • 1985/1/20
  • 2006/3/12
  • Sample Output
  • 20
  • 71
全代码

(显然这是个笨方法,如果有好的做法还请各位大佬多多指教)

import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int year, month, day, num = 0;

        while (sc.hasNext()) {
            String pattern = sc.next();
            String[] list = pattern.split("/");
            year = Integer.parseInt(list[0]);
            month = Integer.parseInt(list[1]);
            day = Integer.parseInt(list[2]);
            // System.out.println("年"+year+" 月"+month+" 日"+day);

            if(isCommonYear(year)) {
                switch (month) {
                    case 1:
                        num = day;
                        break;
                    case 2:
                        num = day+31;
                        break;
                    case 3:
                        num = 31+28+day;
                        break;
                    case 4:
                        num = 31+28+31+day;
                        break;
                    case 5:
                        num = 31+28+31+30+day;
                        break;
                    case 6:
                        num = 31+28+31+30+31+day;
                        break;
                    case 7:
                        num = 31+28+31+30+31+30+day;
                        break;
                    case 8:
                        num = 31+28+31+30+31+30+31+day;
                        break;
                    case 9:
                        num = 31+28+31+30+31+30+31+31+day;
                        break;
                    case 10:
                        num = 31+28+31+30+31+30+31+31+30+day;
                        break;
                    case 11:
                        num = 31+28+31+30+31+30+31+31+30+31+day;
                        break;
                    case 12:
                        num = 31+28+31+30+31+30+31+31+30+31+30+day;
                        break;
                }
            } else {
                switch (month) {
                    case 1:
                        num = day;
                        break;
                    case 2:
                        num = day+31;
                        break;
                    case 3:
                        num = 31+29+day;
                        break;
                    case 4:
                        num = 31+29+31+day;
                        break;
                    case 5:
                        num = 31+29+31+30+day;
                        break;
                    case 6:
                        num = 31+29+31+30+31+day;
                        break;
                    case 7:
                        num = 31+29+31+30+31+30+day;
                        break;
                    case 8:
                        num = 31+29+31+30+31+30+31+day;
                        break;
                    case 9:
                        num = 31+29+31+30+31+30+31+31+day;
                        break;
                    case 10:
                        num = 31+29+31+30+31+30+31+31+30+day;
                        break;
                    case 11:
                        num = 31+29+31+30+31+30+31+31+30+31+day;
                        break;
                    case 12:
                        num = 31+29+31+30+31+30+31+31+30+31+30+day;
                        break;
                }
            }

            System.out.println(num);
        }
    }

    private static boolean isCommonYear(int year) {
        return !(year % 400 == 0 || (year % 4 == 0 && year % 100 != 0));
    }
}

HD2006

linkOJ

  • @description
  • 给你n个整数,求他们中所有奇数的乘积。
  • Input
  • 输入数据包含多个测试实例,每个测试实例占一行,每行的第一个数为n,
  • 表示本组数据一共有n个,接着是n个整数,你可以假设每组数据必定至少存在一个奇数。
  • Output
  • 输出每组数中的所有奇数的乘积,对于测试实例,输出一行。
  • Sample Input
  • 3 1 2 3
  • 4 2 3 4 5
  • Sample Output
  • 3
  • 15
全代码
import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while(sc.hasNextInt()) {
            int counter = sc.nextInt();
            int[] list = new int[counter];
            for (int i = 0; i < counter; i++) {
                list[i] = sc.nextInt();
            }
            System.out.println(getMultiOfOdd(list));
        }
    }

    private static int getMultiOfOdd(int[] list) {
       /* for (int i = 0; i < list.length; i++) {
            System.out.println(list[i]);
        }*/
        int result = 1;
        for (int n : list) {
            // System.out.println(n);
            if(n%2!=0) {
                // 奇数
                result*=n;
            }
        }
        return result;
    }
}

HD2007

linkOJ

  • @description
  • 给定一段连续的整数,求出他们中所有偶数的平方和
  • 以及所有奇数的立方和。
  • @Input
  • 输入数据包含多组测试实例,每组测试实例包含一行,由两个整数m和n组成。
  • @Output
  • 对于每组输入数据,输出一行,应包括两个整数x和y,
  • 分别表示该段连续的整数中所有偶数的平方和以及所有奇数的立方和。
  • 你可以认为32位整数足以保存结果。
  • @Sample_Input
  • 1 3
  • 2 5
  • @Sample_Output
  • 4 28
  • 20 152
编码中遇到的问题
  1. 乍看这一真的把我搞蒙蔽了。
    描述中给定一段连续的整数:
    那这个一段连续的整数到底在哪里?
    1 3 2 5无论是被看成一组还是两组数,都似是非是无法还原输出结果。
    最后我没忍住搜了其他人的答案——
    原来题目的意思是,输入的m n也就是示例中的1 3或者2 5只是个数字的范围。(在1~3之间的数;在2~5之间的数;包括两端的数)
    题目意思是:
    求m和n之间(包括m和n)偶数的平方和、奇数的立方和。

  2. 当然还有一个很需要注意的地方是,一定要注意输入两个范围数字的大小,可能是先输入的数字小,也可能是先输入的数字大,在获取输入之后要判断一下。

全代码
import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int a, b, start, end;
        // 偶数平方和
        int evenSum;
        // 奇数立方和
        int oddSum ;
        while (sc.hasNextInt()) {
            evenSum = 0;
            oddSum = 0;
            a = sc.nextInt();
            b = sc.nextInt();
            if(a>b) {
                start = b;
                end = a;
            } else {
                start = a;
                end = b;
            }
            for (int i = start; i < end + 1; i++) {
                if(i%2==0) {
                    evenSum+=(i*i);
                } else {
                    oddSum+=(i*i*i);
                }
            }
            System.out.println(evenSum+" "+oddSum);
        }
    }
}

HD2008

linkOJ

  • @description
  • 统计给定的n个数中,负数、零和正数的个数。
  • Input
  • 输入数据有多组,每组占一行,每行的第一个数是整数n(n<100),
  • 表示需要统计的数值的个数,然后是n个实数;如果n=0,则表示输入结束,该行不做处理。
  • Output
  • 对于每组输入数据,输出一行a,b和c,分别表示给定的数据中负数、零和正数的个数。
  • Sample Input
  • 6 0 1 2 3 -1 0
  • 5 1 2 3 4 0.5
  • 0
  • Sample Output
  • 1 2 3
  • 0 0 5
全代码
import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        // 负数个数
        int num1;
        // 零的个数
        int num2;
        // 正数个数
        int num3;
        int counter;
        double d;
        Scanner sc = new Scanner(System.in);
        while (true) {
            num1 = num2 = num3 = 0;
            counter = sc.nextInt();
            if(counter==0) {
                break;
            } else {
                for (int i = 0; i < counter; i++) {
                    d = sc.nextDouble();
                    if(d<0) {
                        num1++;
                    } else if(d==0) {
                        num2++;
                    } else {
                        num3++;
                    }
                }
                System.out.println(num1+" "+num2+" "+num3);
            }
        }
    }
}

HD2009

linkOJ

  • @description
  • 数列的定义如下:
  • 数列的第一项为n,以后各项为前一项的平方根,求数列的前m项的和。
  • Input
  • 输入数据有多组,每组占一行,由两个整数n(n<10000)和m(m<1000)组成,n和m的含义如前所述。
  • Output
  • 对于每组输入数据,输出该数列的和,每个测试实例占一行,要求精度保留2位小数。
  • Sample Input
  • 81 4
  • 2 2
  • Sample Output
  • 94.73
  • 3.41

全代码

import java.text.DecimalFormat;
import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        double n;
        int m;
        double sum;
        while (sc.hasNext()) {
            sum = 0;
            n = sc.nextDouble();
            m = sc.nextInt();
            for (int i = 0; i < m; i++) {
                sum+=n;
                n = Math.sqrt(n);
            }
            DecimalFormat format = new DecimalFormat("#.00");
            System.out.println(format.format(sum));
        }
    }
}

HD2010

linkOJ

  • @description
  • 春天是鲜花的季节,水仙花就是其中最迷人的代表,数学上有个水仙花数,他是这样定义的:
  • “水仙花数”是指一个三位数,它的各位数字的立方和等于其本身,比如:153=13+53+3^3。
  • 现在要求输出所有在m和n范围内的水仙花数。
  • @Input
  • 输入数据有多组,每组占一行,包括两个整数m和n(100<=m<=n<=999)。
  • @Output
  • 对于每个测试实例,要求输出所有在给定范围内的水仙花数,就是说,输出的水仙花数必须大于等于m,并且小于等于n,
  • 如果有多个,则要求从小到大排列在一行内输出,之间用一个空格隔开;
  • 如果给定的范围内不存在水仙花数,则输出no;
  • 每个测试实例的输出占一行。
  • @Sample_Input
  • 100 120
  • 300 380
  • @Sample_Output
  • no
  • 370 371
编码中遇到的问题
  1. 又在输出的格式上绕圈子了。简直是 佛系输出格式。要求是:没有水仙花数就输出no;如果有的化按照从小到大逐个输出,并且每个数之间有空格,一定要注意最后一个数 不加空格,但要换行。之前我一般都是把空格加在每个输出的后面,再判断是不是到了最后一个数了,直来直去的;其实把空格看成是加载数字前面的,那么只有第一个数是特殊情况的-不需要在它前面加空格,而其他的数都需要,就像这样写:
if(i == 0) {
	System.out.print(results[i]);
	} else {
	System.out.print(" "+results[i]);
	}
  1. 判定条件的细节问题,但是导致了程序未能通过。写成if(counter == 0)还是if(result[0] == 0)。结果是if(counter == 0)是对的。但是我不太能理解。详情请看我在CSDN论坛的提问下的回答和回复。
  2. 能用数组不用List<>(省运行时间);能不用数组就不用数组(避免越界问题 或者 在循环中数组的值没有更新);能用foreach就不用for(foreach貌似运行速度更快)
全代码
import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int start, end;
        while (sc.hasNext()) {
            int[] results = new int[Short.MAX_VALUE];
            start = sc.nextInt();
            end = sc.nextInt();
            int counter = 0;
            for (int i = start; i < end + 1; i++) {
                if(isSpecial(i)) {
                    // 将结果先放在数组中,方便控制输出和换行
                    results[counter] = i;
                    counter++;
                }
            }
            if(counter == 0) {
                System.out.println("no");
            } else {
                for (int i = 0; i < counter; i++) {
                    if(i == 0) {
                        System.out.print(results[i]);
                    } else {
                        System.out.print(" "+results[i]);
                    }
                }
                System.out.println();
            }
        }
    }

    private static boolean isSpecial(int n) {
        int a, b, c;
        // 个位
        a = n%10;
        // 十位
        b = (n/10)%10;
        // 百位
        c = (n/100);
        return (a*a*a + b*b*b + c*c*c) == n;
    }
}
更优化的解决方案

原文

import java.util.Scanner;
public class Main2 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int i, j, n, m, a, b, c;
        while (sc.hasNextInt()) {
            m = sc.nextInt();
            n = sc.nextInt();
            for (i = m, j = 0; i <= n; i++) {
                a = i / 100;
                b = i / 10 % 10;
                c = i % 10;
                if (a * a * a + b * b * b + c * c * c == i) {
                    if (j > 0) {
                        System.out.print(" " + i);
                    } else {
                        System.out.print(i);
                    }
                    j++;
                }
            }
            if (j == 0) {
                System.out.print("no");
            }
            System.out.println();
        }
    }
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值