一、选择题
(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;
}