//在N行N列的数阵中, 数K(1〈=K〈=N)在每行和每列中出现且仅
// 出现一次,这样的数阵叫N阶拉丁方阵。例如下图就是一个五阶拉丁方阵。
// 编一程序,从键盘输入N值后,打印出所有不同的N阶拉丁方阵,并统计个数。//        1  2  3  4  5
//        2  3  4  5  1
//        3  4  5  1  2
//        4  5  1  2  3
 //       5  1  2  3  4

解决方案 »

  1.   

    这和对象有关吗?class LaDing {
        private int[] num = null;    public LaDing(int n) {
            num = new int[n];
            for (int i = 0; i < num.length; i++) {
                num[i] = i + 1;
            }
        }    public int get(int row, int col) {
            return num[(row + col) % num.length];
        }    public void print() {
            for (int i = 0; i < num.length; i++) {
                for (int j = 0; j < num.length; j++) {
                    System.out.print(get(i, j) + " ");
                }
                System.out.println();
            }
        }
    }
      

  2.   

    上面那个还是笨了,第一感觉要用数组,其实完全没必要。class LaDing {
        private int n = 1;    public LaDing(int n) {
            this.n = n;
        }    public int get(int row, int col) {
            return (row + col) % n + 1;
        }    public void print() {
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < n; j++) {
                    System.out.print(get(i, j) + " ");
                }
                System.out.println();
            }
        }
    }
      

  3.   

    import java.io.IOException;
    import java.io.*;public class LatinSquareMatrix { //方阵阶数
    int n;
    //矩阵数组
    int[][] arr ;
    public LatinSquareMatrix(int n) {
    // TODO Auto-generated constructor stub
    this.n = n;
    arr = new int[n][n];
    makeMatrix(n);
    }
    public void makeMatrix(int n){
    for (int i=0;i<n;i++){
    arr[0][i] = i+1;
    }
    for (int j=1;j<n;j++){
    for (int k=0;k<n;k++){
    if (arr[j-1][k]==n){
    arr[j][k]=1;
    } else {
    arr[j][k]=arr[j-1][k]+1;
    }
    }
    }
    }
    public void printMatrix(){
    for (int i=0;i<n;i++){
    for (int j=0;j<n;j++){
    System.out.print(arr[i][j]);
    }
    System.out.println();
    }
    System.out.println("共"+n*n+"个数字");

    }
    public static void main(String[] args) throws IOException {
    System.out.print("请输入:"); 
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 
    String num ="";
    try 

    num = br.readLine(); 
    } catch (IOException e) { 
    e.printStackTrace(); 


    LatinSquareMatrix lsm = new LatinSquareMatrix(Integer.parseInt(num));
    lsm.printMatrix();
    }
    }
    运行结果:请输入:5
    12345
    23451
    34512
    45123
    51234
    共25个数字
      

  4.   

    import java.io.*;class LaDing {
    private int n;

    public LaDing(int n) {
    this.n = n;
    }

    public int get(int row,int col) {
    return (row+ col)% n+1;
    }

    public void print() {
    for (int i=0; i< n; i++) {
    for (int j=0; j< n; j++) {
    System.out.print(get(i, j)+" ");
    }
    System.out.println();
    }
    }

    public static void main(String[] args) throws IOException {
    int n = 1;
    String num = null;
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    while((num = br.readLine()) != null) {
    n = Integer.parseInt(num);
    break;
    }
    LaDing ld = new LaDing(n);
    ld.print();

    }
    }还不怎么完善,自己改进改进!
      

  5.   

    楼上各位给的都是什么答案呀,人家要的是所有的方阵,你们的程序给出的只有一个结果。
    我用的是回溯法,能够打印所有的方阵。
    对于N=3时,有12个结果。N=4时,有576个结果。N=5时,结果太多了(>80000),打印要很久。
    N=3时的结果如下:
    1
    123
    231
    312
    ================
    2
    123
    312
    231
    ================
    3
    132
    213
    321
    ================
    4
    132
    321
    213
    ================
    5
    213
    132
    321
    ================
    6
    213
    321
    132
    ================
    7
    231
    123
    312
    ================
    8
    231
    312
    123
    ================
    9
    312
    123
    231
    ================
    10
    312
    231
    123
    ================
    11
    321
    132
    213
    ================
    12
    321
    213
    132
    ================
    class LaDing {
        final int n;
        int[][] m;
        int count = 0;
        
        LaDing(int n) {
            this.n = n;
            m = new int[n][n];
            fill(0);
        }
        
        boolean check(int i, int j, int a) {
            for(int col=0; col<j; col++)
                if(m[i][col] == a) return false;
            for(int row=0; row<i; row++)
                if(m[row][j] == a) return false;
            return true;
        }
        
        void fill(int i) {
            int row = i/n;
            int col = i%n;
            for(int a=1; a<=n; a++) {
                if(check(row, col, a)) {
                    m[row][col] = a;
                    if(i == n*n-1) {
                        count++;
                        System.out.println(count);
                        for(int[] line : m) {
                            for(int x : line)
                                System.out.print(x);
                            System.out.println();
                        }
                        System.out.println("================");
                    }
                    else fill(i+1);
                }
            }
        }
        
        public static void main(String[] args) {
            new LaDing(3);
        }
    }
      

  6.   

    时间都是花在打印上了,因为输入输出总是比较慢的。
    可以加个条件语句,决定是否打印:
    if(print) { .... }如果不打印数组,只输出总数的话,还是很快的
    N=5时 结果总数为 161280可以利用对称性,来加速计算,把一个结果上下翻转、左右翻转,镜像翻转,交换两列,交换两行...,等等操作都可以得到新的结果。但是比较麻烦,因为你得保证没有重复的。
      

  7.   

    先列举 N!个行排列结果   arraylist<String>
    然后生成N-1组(重点)标记,
    利用对称性,来加速计算,把一个组里面的行列交换两行...可迅速计算出有N个排列
    这样就可以得出总共有(N-1)*N!个结果
    利用标记获取序列的元素打印
      

  8.   

    例子:N=3
    列举arraylist[3*2]=
    123   0
    132   1
    213   2
    231   3
    312   4
    321   5
    生成3-1=2组基础拉丁方阵
    123  132
    231  213 
    312  312
    标记034,125
    利用交换,生成最后的标记,这里也可以用arraylist进行移位
    输出结果:(N-1)*N!
    打印结果;
      
      

  9.   

    例子:N=3
    列举arraylist[3*2]=
    123   0
    132   1
    213   2
    231   3
    312   4
    321   5
    生成P(N-1)!=2组基础拉丁方阵
    123  132
    231  213 
    312  312
    标记034,125
    利用交换,生成最后的标记,这里也可以用arraylist进行移位
    输出结果:P(N-1)!*N!
    打印结果;找个才是
      

  10.   


    class LaDing {
        private int n = 1;    public LaDing(int n) {
            this.n = n;
        }    public int get(int row, int col) {
            return (row + col) % n + 1;
        }    public void print() {
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < n; j++) {
                    System.out.print(get(i, j) + " ");
                }
                System.out.println();
            }
        }
        
        public static void main(String args[]) {
         new LaDing(5).print() ;
        }
    }
    很强
      

  11.   

    fucking那个鸡巴设个下载分10的,弄的我下不了郁闷
    另外,上面写错了点:
    应该是 生成(N-1)!(N-2)!···2!*1组(重点)标记所以生成的总数是:*N(N-1)!(N-2)···2!*1
    n=3,  为12
    n=4      288
      

  12.   

    。。
    N!(N-1)!(N-2)···2!*1