java判断44数组是否是4阶幻方_2015蓝桥杯决赛Java A组 第二题--四阶幻方

//把1~16的数字填入4x4的方格中,使得行、列以及两个对角线的和都相等,满足这样的特征时称为:四阶幻方。

//

//四阶幻方可能有很多方案。如果固定左上角为1,请计算一共有多少种方案。

//比如:

// 1 2 15 16

// 12 14 3 5

// 13 7 10 4

// 8 11 6 9

//

//以及:

// 1 12 13 8

// 2 14 7 11

// 15 3 10 6

// 16 5 4 9

//

//就可以算为两种不同的方案

import java.util.LinkedList;

public class Main {

private static final int Element_NUM = 16;

private static final int ROW = 4;

private static final int COL = 4;

private static LinkedList set = new LinkedList();

private static int[][] arr = new int[ROW][COL];

private static int count = 0;

public static void main(String[] args) {

// TODO Auto-generated method stub

arr[0][0]=1;

set.add(1);

dfs(0, 1);

System.out.println(count);

}

/**

* 往数组放元素,回溯,剪枝

* @param row

* @param col

*/

private static void dfs(int row, int col) {

for (int i = 1; i <= Element_NUM; i++) {

if (!set.contains(i)) {

arr[row][col] = i;

set.add(i);

} else

continue;

//生成元素时判断前3行是否符合条件,不符合重新生成---

if (row == 0 && col == (COL-1 )) {

if (getRowSum(0) != 34) {

//print(true);

arr[row][col]=0;

set.removeLast();

if (i==Element_NUM) {

return;

}

continue;

}

}

if (row == 1 && col == (COL - 1)) {

if (getRowSum(1) != 34) {

arr[row][col]=0;

set.removeLast();

if (i==Element_NUM) {

return;

}

continue;

}

}

if (row == 2 && col == (COL - 1)) {

if (getRowSum(2) != 34) {

arr[row][col]=0;

set.removeLast();

if (i==Element_NUM) {

return;

}

continue;

}

}

//------------------------------

if (col < COL - 1)

dfs(row, col + 1);

else if (row < ROW - 1 && col == COL - 1)

dfs(row + 1, 0);

//到达最后一个数

if (row == ROW - 1 && col == COL - 1) {

//判断该矩阵是否符合四阶幻方

if(colIsReasonable()){

count++;

}

}

set.removeLast();

}

}

/**

* 获取某行的所有元素之和

* @param row

* @return

*/

private static int getRowSum(int row) {

int sum = 0;

for (int i = 0; i < COL; i++) {

sum += arr[row][i];

}

return sum;

}

/**

* 判断列和斜列是否合理

* @return

*/

private static boolean colIsReasonable() {

int sum=0;

//列,向下

for (int i = 0; i < COL; i++) {

for (int j = 0; j < ROW; j++) {

sum+=arr[j][i];

}

if(sum!=34)

return false;

sum=0;

}

sum=0;

//斜列,向右下

for (int i = 0; i < COL; i++) {

sum+=arr[i][i];

}

if(sum!=34)

return false;

sum=0;

//斜列,向右上

for (int i = COL-1; i >=0; i--) {

sum+=arr[i][COL-1-i];

}

if(sum!=34)

return false;

return true;

}

}

结果:416

虽然经过剪枝,但是这个算法还是非常耗时的,大概一两分钟才能得出结果,这种题应该是填空题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值