幻方问题:一个n*n的矩阵中填入1到n*n的数字,使得每一行每一列每条对角线的累加和都相等。
Posted tacit-lxs
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了幻方问题:一个n*n的矩阵中填入1到n*n的数字,使得每一行每一列每条对角线的累加和都相等。相关的知识,希望对你有一定的参考价值。
题目:幻方又称魔方阵,游戏规则是在一一个n*n的矩阵中填入1到n*n的数字,使得每一行、每一列、每条对角线的累加和都相等。
思路:
回溯加剪枝:将矩阵用递归不重复的填满,用回溯的方法枚举每一种填入的情况,
比如arr[0][0]可以填入1到n*n的任意一个未被填入的数字。
然后判断是否满足幻方的条件。
代码:
public calss Main
public static void main(String[] args)
Scanner scanner = new Scanner(System.in);
System.out.println("请输入行数:");
int N = scanner.nextInt();
System.out.println("请输入列数:");
int M = scanner.nextInt();
int num = N*M+1;
myPrintAnswer(N,M,num);
private static void myPrintAnswer(int n, int m, int num)
int[][] arr = new int[n][m];
int total = 0;
for (int i = 1; i < num; i++)
total += i;
//根据total可以算出幻方的各行、各列及对角线之和的值:total/行数或列数
System.out.println(total);
boolean[] booleans = new boolean[num];
dfs(0,arr,booleans,num,n,m,total);
//递归的将arr填满
private static void dfs(int i,int[][] arr, boolean[] booleans,int num,int n,int m,int total)
if (i == num - 1 && check(arr))
//打印结果
myPrint(arr);
System.out.println("-------");
return;
if(i >= n )
int sum = 0;
for (int j = 0; j < arr[0].length; j++)
sum += arr[0][j];
//剪枝
if(sum != total/n) return;
for (int k = 1; k < num; k++)
if(!booleans[k])
booleans[k] = true;
arr[i/m][i%m] = k;
dfs(i+1,arr,booleans,num,n,m,total);
booleans[k] = false;
//打印矩阵
private static void myPrint(int[][] arr)
for (int i = 0; i < arr.length; i++)
for (int j = 0; j < arr[0].length; j++)
if(j <arr.length -1)
System.out.print( arr[i][j]+ "-");
else
System.out.print(arr[i][j]);
System.out.println();
//判断是否满足构成幻方条件
private static boolean check(int[][] arr)
int num = 0;
for (int i = 0; i < arr[0].length; i++)
num += arr[0][i];
//求每行之和
for(int i = 0;i < arr[0].length;i++)
int num1 = 0;
for (int j = 0; j < arr.length; j++)
num1 += arr[i][j];
if(num != num1) return false;
//求每列之和
for (int i = 0; i < arr.length; i++)
int num2 = 0;
for (int j = 0; j < arr[0].length; j++)
num2 += arr[j][i];
if(num != num2) return false;
int i = 0,j = 0;
int num3 = 0;
//对角线之和
while (i < arr.length && j < arr.length)
num3 += arr[i][j];
i++;
j++;
if(num3 != num) return false;
i = 0;
j = arr[0].length-1;
int num4 = 0;
while (i < arr.length && j >= 0)
num4 += arr[i][j];
i++;
j--;
if(num4 != num) return false;
return true;
以上是关于幻方问题:一个n*n的矩阵中填入1到n*n的数字,使得每一行每一列每条对角线的累加和都相等。的主要内容,如果未能解决你的问题,请参考以下文章