笔试强训(二十九)

一、选择题

(1)下列关于java语言特点,描述错误的是(C)
A.java是跨平台的编程语言
B.java支持分布式计算
C.java是面向过程的编程语言
D.java支持多线程

java是面向对象的语言

(2)Java语言用以下哪个类把基本类型数据封装为对象(A)
A.包装类
B.Class
C.Math
D.Object

(3)以下程序的执行结果是:(C)
在这里插入图片描述
A.ZYXX
B.ZYXY
C.YXYZ
D.XYZX

  • 继承时先调用父类的构造方法
  • 类中成员变量的初始化操作都在构造方法中进行

类的实例变量的初始化通过构造方法,实现调用X的构造方法,在X的构造方法中先初始化实例成员变量y(也就是调用Y的构造方法,打印Y),然后打印X,然后调用Z的构造方法,在Z的构造方法种先初始实例成员变量y(也就是调用Y的构造方法,打印Y),然后打印Z

二、编程题

2.1 有假币

2.1.1 题目

在这里插入图片描述

2.1.2 题解

思路题目要求以最快的方式找出假币,每次都将硬币分成三堆,称其中的两堆这样的方式是最快的,因为每次都能淘汰两堆硬币

在这里插入图片描述
(1)如果A>B,那么假币在A
(2)如果A<B,那么假币在B
(3)如果A==B,那么假币在C

可能硬币的数量不能平均分成三分,因此我们称的是3堆中数量相等的那两堆
例如n=5,分成2,2,1这三堆,称2,2这两堆,因为只有每次用天平称的两堆硬币的数量是相等的,才能最快的找出假币

同时题目问最多称几次,一定能找到假币,因此我们要考虑最坏的情况,就是每次都假设假币在三份中最多的那份里
例如:

n=4,分成1,1,2三堆,假设假币在2这堆里,因为如果假币在1的堆中,只需称1次就知道结果,而如果假币在2这堆中,就要称2次才知道结果
n=5,分成2,2,1三堆,假设假币在堆为2的其中一个堆中,因为如果假币在1的堆中,只需称1次就知道结果,而如果假币在2这堆中,就要称2次才知道结果

代码:

import java.util.*;
public class Main{
    public static void main(String[] args){
        
        Scanner scanner=new Scanner(System.in);
        while(scanner.hasNextInt()){
            int n=scanner.nextInt();
            if(n==0)break;
            int count=0;
            while(n>=2){
                if(n%3==0){
                    n=n/3;
                }else {
                    n=n/3+1;
                }
                count++;
            }
            System.out.println(count);
        }
    }
}

2.2 求正数数组的最小不可组成和

2.2.1 题目

在这里插入图片描述

2.2.2 题解

思路:dp[i][j]表示[0…i]范围内的元素任意累加,能否组成j这个累加和。
初始情况:dp[0][arr[0]]=true,dp[i][0]=true;(i的范围是0…arr.length-1);
递归公式:dp[i][j]=dp[i-1][j] ||dp[i-1][j-arr[i]];
[0…i]范围内,任意选择,能否组成j这个累加和,其实包括了两种情况:

情况1:[0…i-1]范围内,任意选择,能否组成j这个累加和,如果可以,说明dp[i][j]=true
情况2:[0…i-1]范围内,任意选择,能否组成j-arr[i]这个累加和(注意不能越界),如果可以,说明dp[i][j]

代码:

public int getFirstUnFormedNum(int[] arr) {
     int min=arr[0];
        int max=arr[0];
        for(int i=1;i<arr.length;i++){
            min=Math.min(arr[i],min);
            max+=arr[i];
        }
        boolean[][] dp=new boolean[arr.length][max+1];
        dp[0][arr[0]]=true;
        for(int i=0;i<arr.length;i++){
            dp[i][0]=true;
        }
        for(int i=1;i<arr.length;i++){
            for(int j=1;j<=max;j++){
                dp[i][j]=dp[i-1][j]||((j-arr[i]>=0) && dp[i-1][j-arr[i]]);
            }
        }
        for(int j=min;j<=max;j++){
            if(!dp[arr.length-1][j]){
                return j;
            }
        }
        return max+1;
	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值