首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

Java 解決拉丁方陣問題:判斷拉丁方陣、標準拉丁方陣完整實現

     編輯:程式設計疑難解答

題目要求

輸入 n 階方陣,判斷是否為拉丁方陣(每行每列包含 1..n 各一次),進一步判斷是否為標準拉丁方陣(首行首列按 1..n 遞增)。

核心邏輯

  1. 讀取 n,再讀 n 行 n 列整數存入 `List`(扁平化)。
  2. 首行和為基準和,構建集合驗證元素唯一性(1..n)。
  3. 逐行、逐列累加驗證和等於基準和,且元素都在集合中。
  4. 標準拉丁方陣:首行 1..n 遞增、首列 1..n 遞增(步長 n)。

完整代碼(精簡版)

import java.util.*;

public class LatinSquare {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (true) {
            System.out.print("階數 n (0退出): ");
            int n = sc.nextInt();
            if (n <= 0) break;
            
            int[] a = new int[n * n];
            for (int i = 0; i < n * n; i++) a[i] = sc.nextInt();
            
            boolean latin = checkLatin(n, a);
            boolean standard = latin && checkStandard(n, a);
            
            if (standard) System.out.println("2 - 標準拉丁方陣");
            else if (latin) System.out.println("1 - 拉丁方陣");
            else System.out.println("0 - 非拉丁方陣");
        }
    }

    static boolean checkLatin(int n, int[] a) {
        // 檢查元素範圍 1..n
        boolean[] seen = new boolean[n + 1];
        int sum = 0;
        for (int i = 0; i < n; i++) {
            int v = a[i];
            if (v < 1 || v > n || seen[v]) return false;
            seen[v] = true;
            sum += v;
        }
        // 行列和驗證
        for (int i = 0; i < n; i++) {
            int rowSum = 0, colSum = 0;
            for (int j = 0; j < n; j++) {
                int rv = a[i * n + j];
                int cv = a[j * n + i];
                if (rv < 1 || rv > n || cv < 1 || cv > n) return false;
                rowSum += rv;
                colSum += cv;
            }
            if (rowSum != sum || colSum != sum) return false;
        }
        return true;
    }

    static boolean checkStandard(int n, int[] a) {
        // 首行 1..n
        for (int j = 0; j < n; j++) if (a[j] != j + 1) return false;
        // 首列 1..n
        for (int i = 0; i < n; i++) if (a[i * n] != i + 1) return false;
        return true;
    }
}

關鍵點

  • 扁平化一維陣列 `a[i*n+j]` 訪問二維邏輯,簡化索引。
  • 首行和作為基準,行列和必須一致(必要非充分條件,配合元素範圍 1..n 即充分)。
  • 標準拉丁方陣只需檢查首行首列遞增,因拉丁方陣性質已保證其餘行列為循環移位。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved