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>0
,m>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 ?
本来以为是水题,后来觉得没这么简单,然后用 Double
,euqal
函数,还是错。后面百度了一下,他们是用字符串,把后面的.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;
}
}
}