首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 學習筆記:階段測試題解析——楊輝三角、彈球問題、兔子繁殖、燈泡開關、換啤酒

     編輯:Java 相關知識

本文整理 5 道經典 Java 基礎階段測試題,涵蓋二維數組操作、數學建模、遞歸與迭代、位運算優化、贪心算法等核心考點,提供完整代碼實現與多種解法對比。

題目一:楊輝三角變體打印

需求

鍵盤輸入行數 n,打印前 n 行楊輝三角,每行居中顯示。

規律分析

  1. 第 i 行有 i 個數 (i 從 1 開始)
  2. 第 1、2 行全為 1;第 3 行起,首尾為 1
  3. 中間元素:arr[i][j] = arr[i-1][j] + arr[i-1][j-1]

代碼實現

public class YangHuiTriangle {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.print("請輸入行數: ");
        int rows = sc.nextInt();
        sc.close();
        
        int[][] triangle = new int[rows][];
        // 1. 初始化每行長度、首尾賦值 1
        for (int i = 0; i < rows; i++) {
            triangle[i] = new int[i + 1];
            triangle[i][0] = triangle[i][i] = 1;
        }
        // 2. 填充中間值
        for (int i = 2; i < rows; i++) {
            for (int j = 1; j < i; j++) {
                triangle[i][j] = triangle[i-1][j] + triangle[i-1][j-1];
            }
        }
        // 3. 打印 (居中縮進)
        printTriangle(triangle);
    }
    
    static void printTriangle(int[][] arr) {
        for (int i = 0; i < arr.length; i++) {
            // 縮進: 每行前打印 (總行數 - 當前行 - 1) 個制表符
            for (int k = 0; k < arr.length - i - 1; k++) System.out.print("\t");
            // 打印數值
            for (int val : arr[i]) System.out.print(val + "\t");
            System.out.println();
        }
    }
}

題目二:自由落體彈球問題

需求

小球從 100m 高度落下,每次彈起高度為原高度一半。求第 10 次落地時總路程、第 10 次彈起高度。

數學建模

  • 初始高度 H = 100
  • 第 1 次落地:距離 = H
  • 第 i 次彈起 (i≥1):高度 = H / 2^i
  • 第 i+1 次落地:距離 = 2 × (H / 2^i) = H / 2^(i-1)
  • 第 10 次落地總距離 = H + 2×Σ(H/2^i) i=1..9

代碼實現 (單循環優化)

public class BouncingBall {
    public static void main(String[] args) {
        double height = 100.0;
        double distance = height; // 第一次落下
        
        for (int i = 1; i <= 10; i++) {
            height /= 2; // 彈起高度
            if (i < 10) distance += height * 2; // 彈起+落下
            if (i == 10) System.out.printf("第10次彈起高度: %.4f 米%n", height);
        }
        System.out.printf("第10次落地總路程: %.4f 米%n", distance);
    }
}

輸出:第 10 次彈起高度 ≈ 0.0977 米,總路程 ≈ 299.6094 米。


題目三:斐波那契兔子繁殖

需求

一對兔子第 3 個月開始每月產一對,新生兔第 3 月同樣產仔,不死。求第 20 月總數。

規律

經典斐波那契數列:F(1)=1, F(2)=1, F(n)=F(n-1)+F(n-2) (n≥3)
第 n 月兔子對數 = F(n),總隻數 = 2 × F(n)

三種實現對比

方法時間複雜度空間複雜度代碼關鍵點
遞歸O(2^n) 指數級O(n) 棧簡潔但極慢,n=40 明顯卡頓
數組迭代O(n)O(n)自底向上,存儲歷史值
滾動變量O(n)O(1) ⭐僅保留前兩值,最優

最優解:滾動變量

public class RabbitFibonacci {
    public static void main(String[] args) {
        int month = 20;
        long a = 1, b = 1; // F(1), F(2)
        for (int i = 3; i <= month; i++) {
            long c = a + b;
            a = b;
            b = c;
        }
        System.out.printf("第 %d 月兔子總數: %d 隻%n", month, b * 2);
    }
}

結果:第 20 月共 13462 隻。


題目四:燈泡開關問題 (因子/完全平方數)

需求

n 盞燈初始全關。第 i 個學生拉動 i 的倍數編號燈的開關。n 位學生過後,亮燈數量?

核心洞察

  • 燈 k 被拉動次數 = k 的因數個數
  • 因數成對出現,除非 k 是完全平方數 (如 16: 1×16, 2×8, 4×4),因數個數為奇數
  • 奇數次拉動 → 亮;偶數次 → 關
  • 亮燈編號即為 1~n 內的完全平方數

代碼實現 (O(√n) 數學解 vs O(n log n) 模擬解)

public class LightSwitch {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.print("輸入燈數/學生數 n (1-65535): ");
        int n = sc.nextInt();
        sc.close();
        
        if (n < 1 || n > 65535) { System.out.println("輸入超出範圍"); return; }
        
        // 數學解: 完全平方數個數 = floor(sqrt(n))
        int count = (int) Math.sqrt(n);
        System.out.println("亮燈數量: " + count);
        
        // 驗證: 打印亮燈編號
        for (int i = 1; i * i <= n; i++) {
            System.out.print(i * i + " ");
        }
    }
}

模擬解優化技巧:內層循環 for (int j = i; j <= n; j += i) 直接遍歷倍數,避免取模判斷。


題目五:換啤酒問題 (贪心 + 遞歸/迭代)

需求

啤酒 2 元/瓶,2 空瓶或 4 蓋子換 1 瓶。10 元最多喝幾瓶?(不可賒欠)

狀態建模

  • 初始:10 元 → 5 瓶 → 5 空瓶 + 5 蓋子
  • 每輪兌換:新瓶數 = 空瓶/2 + 蓋子/4
  • 更新狀態:空瓶 = 空瓶%2 + 新瓶數、蓋子 = 蓋子%4 + 新瓶數
  • 終止條件:空瓶<2 且 蓋子<4

遞歸實現

public class BeerExchange {
    static int total = 0;
    
    public static void main(String[] args) {
        int initial = 10 / 2; // 5 瓶
        total = initial;
        exchange(initial, initial); // 初始空瓶=蓋子=5
        System.out.println("剩余空瓶: " + bottles);
        System.out.println("剩余蓋子: " + caps);
        System.out.println("最多可喝: " + total + " 瓶");
    }
    
    static int bottles, caps;
    
    static void exchange(int bottle, int cap) {
        if (bottle >= 2 || cap >= 4) {
            int newBottles = bottle / 2 + cap / 4;
            total += newBottles;
            
            bottles = bottle % 2 + newBottles;
            caps = cap % 4 + newBottles;
            
            exchange(bottles, caps);
        }
    }
}

結果:最多喝 9 瓶,剩 1 空瓶、1 蓋子。

迭代版本:用 while 循環替代遞歸,避免棧溢出風險(雖本題數據量極小)。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved