第六题
题目:
方格填数
如下的10个格子
+--+--+--+
| 0| 1| 2|
+--+--+--+--+
| 3| 4| 5| 6|
+--+--+--+--+
| 7| 8| 9|
+--+--+--+
(如果显示有问题,也可以参看【图1.jpg】)
填入0~9的数字。要求:连续的两个数字不能相邻。
(左右、上下、对角都算相邻)
一共有多少种可能的填数方案?
请填写表示方案数目的整数。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。
答案:
1580
import java.util.ArrayList;
import java.util.Scanner;
public class Main {
static int[][] arr=new int[3][4];
static int sum=0;
public static void main(String[] args){
arr[0][0]=1;
arr[2][3]=1;//以上为建立一个3*4的棋盘
for(int i=1;i<4;i++){
arr[0][i]=1;
p(0,i,arr,1);
arr[0][i]=0;
}
for(int i=0;i<4;i++){
arr[1][i]=1;
p(1,i,arr,1);
arr[1][i]=0;
}
for(int i=0;i<3;i++){
arr[2][i]=1;
p(2,i,arr,1);
arr[2][i]=0;
}//以上为下第一颗棋
System.out.println(sum);
}
public static void p(int i,int j,int [][]arr,int num){//下棋递归
if(num==10){//如果下了十颗,sum++
sum++;
return;
}
for(int ii=0;ii<3;ii++){
for(int jj=0;jj<4;jj++){
if(arr[ii][jj]!=1){//棋盘上每个位置判断一次有没有棋子,如果没有,再判断是否和上一颗棋位置相邻,如果也不是,下棋
if(Math.abs(i-ii)>1||Math.abs(j-jj)>1){
arr[ii][jj]=1;
p(ii,jj,arr,num+1);//下棋递归
arr[ii][jj]=0;
}
}
}
}
}
}
分析:题目很简单,网上的代码大都是穷举,于是想写出一种相对时间复杂度最低的算法。
我把三行四列看做棋盘,每一次填数相当于下棋,安装0到9的数依次填,那么只需要保证下的棋和上一颗棋位置不相邻即可。
总结:做出一个算法题无非两点最重要:
难题化简,也就是把它化成一道适合算法的题(这一点最重要的是留意题目的任何一个小条件)
把题化成算法。
算法的本质我觉得是教计算机我们思考问题的思维,然后计算机把我们的思维学习过去,解决问题,所以算法只不过相当于我们依靠计算机解决问题,而不是让计算机解决问题,这一点很重要。