问题描述
publicclassGrid15{int[][]board;Grid15(){board=newint[3][3];}//输出棋盘的格线行privatevoidoutputGridRowBoard(){inti;System.out.print("+");for(i=0;i<5;i++){System.out.print("-");}System.out.println("+");}//输出棋盘的数据行(第i行,i只能为0、1或2)privatevoidoutputGridRowBoard(inti){intj;for(j=0;j<board[i].length;j++)System.out.print("|"+board[i][j]);System.out.println("|");}//输出棋盘publicvoidoutputGrid(){inti;outputGridRowBoard();for(i=0;i<board.length;i++){outputGridRowBoard(i);outputGridRowBoard();}}//初始化数据privatevoiddataInit(){inti,j,k;for(i=0,k=1;i<board.length;i++)for(j=0;j<board[i].length;j++,k++)board[i][j]=k;}//数据结束检测//返回值说明:当数据为最后一个数据时,返回true,否则;返回false//不明白为什么这个是结束的条件//根据判断条件来看,不是只是判断了中间数字是否为5,若为5则返回TRUE,否则返回false?privatebooleandataEnd(){inti,j,k;for(i=0,k=9;i<board.length;i++)for(j=0;j<board[i].length;j++,k--)if(board[i][j]!=k)returnfalse;returntrue;}//取下一个数据//按照我的理解,这个函数好像是把方格上每个数字加1(9变为1),但这样怎么可能穷尽所有情况呢privatevoiddataNext(){inti,j;for(i=board.length-1;i>=0;i--)for(j=board[i].length-1;j>=0;j--)if(board[i][j]==9)board[i][j]=1;else{board[i][j]++;return;}}//数据检测:判断数据中是否含有相同的数字//当数据中存在相同数字时,返回false;否则,返回trueprivatebooleandataCheckDifferent(){inti,j;int[]digit=newint[10];for(i=0;i<board.length;i++)for(j=0;j<board[i].length;j++)digit[board[i][j]]=1;for(i=1,j=0;i<digit.length;i++)j+=digit[i];if(j==9)returntrue;returnfalse;}//数据检测:各行和是否为15//当各行和均为15时,返回true;否则,返回falseprivatebooleandataCheckSumRow(){inti,j,k;for(i=0;i<board.length;i++){for(j=0,k=0;j<board[i].length;j++)k+=board[i][j];if(k!=15)returnfalse;}returntrue;}//数据检测:各列是否为15//当各列和为15时,返回true;否则,返回falseprivatebooleandataCheckSumColumn(){inti,j,k;for(i=0;i<board.length;i++){for(j=0,k=0;j<board[i].length;j++)//原文这一行有问题,已修正k+=board[j][i];if(k!=15)returnfalse;}returntrue;}//数据检测:总方法privatebooleandataCheck(){if(!dataCheckDifferent())returnfalse;if(!dataCheckSumRow())returnfalse;if(!dataCheckSumColumn())returnfalse;//检测对角线之和是否为15if(board[0][0]+board[1][1]+board[2][2]!=15)returnfalse;if(board[0][2]+board[1][1]+board[2][0]!=15)returnfalse;returntrue;}//求解并输出棋盘问题publicvoidarrange(){intn=1;for(dataInit();!dataEnd();dataNext())//关键步骤,括号内三个函数不理解{if(dataCheck())//条件满足,输出{System.out.println("第"+n+"个结果:");n++;outputGrid();}}}publicstaticvoidmain(String[]args){Grid15a=newGrid15();a.arrange();}}
解决方案
解决方案二:
http://blog.csdn.net/itlijunjie/article/details/12586261这里有些注释,参考一下
解决方案三:
你参考的程序也太"穷举"了吧?而且,我试过他的代码了,速度非常慢,中间还有停顿的现象。依我看,这个问题就其实两个关键步骤:第一步、全排列第二步、对于某一种排列,检测其是否符合魔方阵,符合的输出第二步好理解,剩下的就是“全排列”函数了,一个DFS算法即可搞定,而且比他的快多了publicclassAllPerm{publicstaticint[][]qipan=newint[3][3];publicstaticintcount=0;/**深度优先型全排列*/publicstaticvoidallPerm(int[]indexArray,intlevel){if(level==indexArray.length-1){//到达子节点检测、输出checkAndPrint(indexArray);}else{//递归第一个子节点allPerm(indexArray,level+1);for(inti=level+1;i<indexArray.length;i++){//提取前缀swap(indexArray,level,i);//递归对应子树allPerm(indexArray,level+1);//回溯swap(indexArray,level,i);}}}publicstaticvoidcheckAndPrint(int[]indexArray){intindex=0;for(inti=0;i<3;i++){for(intj=0;j<3;j++){qipan[i][j]=indexArray[index];index++;}}//行检测for(inti=0;i<3;i++){intsum=0;for(intj=0;j<3;j++){sum+=qipan[i][j];}if(sum!=15){return;}}//列检测for(intj=0;j<3;j++){intsum=0;for(inti=0;i<3;i++){sum+=qipan[i][j];}if(sum!=15){return;}}//对角线检测intsum=0;for(inti=0;i<3;i++){sum+=qipan[i][i];}if(sum!=15){return;}sum=0;for(inti=0;i<3;i++){sum+=qipan[i][2-i];}if(sum!=15){return;}count++;System.out.println("第"+count+"个结果:");for(inti=0;i<3;i++){for(intj=0;j<3;j++){System.out.print(qipan[i][j]+"");}System.out.println();}}publicstaticvoidswap(int[]array,inta,intb){inttemp=array[a];array[a]=array[b];array[b]=temp;}publicstaticvoidmain(String[]args){int[]indexArray=newint[9];for(inti=0;i<9;i++){indexArray[i]=i+1;}allPerm(indexArray,0);}}