您的位置:首页 > 编程语言 > Java开发

JAVA学习笔记(2):求解和为15的棋盘游戏

2017-07-06 21:27 603 查看
1.问题描述

把1,2,3,4,5,6,7,8,9这九个数字填入3*3的九宫格中,要求实现每行,每列和每个对角线上的数字之和为15。

2.解决思路

2.1 画出九宫格

设计方法mb_outputGridRowBoard画出九宫格,思路大致为

先输出:+—–+

再输出:|数字|数字|数字|

通过输出三次可以形成如下所示的输出图案:

+ - - - - - +

|数字|数字|数字|

+ - - - - - +

|数字|数字|数字|

+ - - - - - +

|数字|数字|数字|

2.2 对填入九宫格中的数据进行判断

设计方法mb_checkAll(),这个方法中又调用 mb_checkRow(),mb_checkCow( ),mb_checkDiag()分别用于判断每行,每列和每个对角线上的数字之和是否为15,如果都是,则返回true,如果不是则返回false。

2.3 如何实现填入九宫格的数据满足要求

在这里我主要通过对数列{1,2,3,4,5,6,7,8,9}求全排列,每一次的排列我将其填入九宫格中,通过方法mb_fullPermutation()实现,这是一个全排列的递归函数。其中交换的部分,由于java中不存在指针的功能,所以在数据交换上面,我把数列设置为了静态变量,这样实现交换。

3.代码部分

/************************
问题描述:
把1-9填入3*3的棋盘中,保证各行,
各列,对角线上的数字之和为15!
*************************/
public class J_Grid15
{
int [] [] m_board;
static int source [] = {1,2,3,4,5,6,7,8,9};
static int count = 1;
J_Grid15()
{
m_board = new int [3] [3];
}

//输出棋盘的格线行
private void mb_outputGridRowBoard()
{
int i;
System.out.print("+");
for(i = 0;i < 5;i++)
{
System.out.print("-");
}
System.out.println("+");
}

//输出棋盘的数据行(第i行,i = 0 1 2)
private void mb_outputGridRowBoard(int i)
{
int j;
for(j = 0;j < m_board[i].length;j++)
{
System.out.print("|"+m_board[i][j]);
}
System.out.println("|");
}

//输出棋盘
public void mb_outputGrid()
{
int i;
mb_outputGridRowBoard();
for(i = 0;i < m_board.length;i++)
{
mb_outputGridRowBoard(i);
mb_outputGridRowBoard();
}
}

//初始化数据
private void mb_dataInit()
{
int i,j,k = 1;
for(i = 0;i < 3;i++)
for(j = 0;j < 3;j++)
m_board[i][j] = k++;
}

//检查行和是否满足15
private boolean mb_checkRow()
{
for(int i = 0;i < 3;i++)
{
if(m_board[i][0]+m_board[i][1]+m_board[i][2] != 15)
return false;
}
return true;
}
//检查列和是否满足15
private boolean mb_checkCow()
{
for(int i = 0;i < 3;i++)
{
if(m_board[0][i]+m_board[1][i]+m_board[2][i] != 15)
return false;
}
return true;
}
//检查对角线和是否满足15
private boolean mb_checkDiag()
{
if(m_board[0][0] + m_board[1][1] + m_board[2][2] != 15)
return false;
if(m_board[0][2] + m_board[1][1] + m_board[2][0] != 15)
return false;
return true;
}
//检查行、列与对角线之和是否满足15
private boolean mb_checkAll()
{
if(!mb_checkRow())
return false;
if(!mb_checkCow())
return false;
if(!mb_checkDiag())
return false;
return true;
}

//数据交换
private void mb_Swap(int lhs, int rhs)
{
int t = source[lhs];
source[lhs] = source[rhs];
source[rhs] = t;
}
//数据求解并输出,原理:对数列进行全排列填入九宫格中进行判断
private void mb_fullPermutation(int source[],int begin,int end)
{
int i = 0,k = 0;

if(begin >= end)  //找到一个全排列
{
for(int j = 0;j < 3;j++)
{
m_board[j][0] = source[k+0];
m_board[j][1] = source[k+1];
m_board[j][2] = source[k+2];
k = k + 3;
}
if(mb_checkAll())
{
System.out.println("第" + count + "种情况:");
count++;
mb_outputGrid();
}
}

else
{
for(i = begin;i < end;i++)
{
if(begin != i)
{
mb_Swap(begin, i);
}
// 递归排列剩余的从begin+1到end的元素
mb_fullPermutation(source, begin + 1, end);

if (begin != i)
{
mb_Swap(begin, i); // 回溯时还原
}
}
}
}

public static void main(String[] args) {
J_Grid15 a = new J_Grid15();
a.mb_fullPermutation(source,0,9);
System.exit(0);
}
}


4.结果

第1种情况:

+—–+

|2|7|6|

+—–+

|9|5|1|

+—–+

|4|3|8|

+—–+

第2种情况:

+—–+

|2|9|4|

+—–+

|7|5|3|

+—–+

|6|1|8|

+—–+

第3种情况:

+—–+

|4|3|8|

+—–+

|9|5|1|

+—–+

|2|7|6|

+—–+

第4种情况:

+—–+

|4|9|2|

+—–+

|3|5|7|

+—–+

|8|1|6|

+—–+

第5种情况:

+—–+

|6|1|8|

+—–+

|7|5|3|

+—–+

|2|9|4|

+—–+

第6种情况:

+—–+

|6|7|2|

+—–+

|1|5|9|

+—–+

|8|3|4|

+—–+

第7种情况:

+—–+

|8|3|4|

+—–+

|1|5|9|

+—–+

|6|7|2|

+—–+

第8种情况:

+—–+

|8|1|6|

+—–+

|3|5|7|

+—–+

|4|9|2|

+—–+
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: