一、题目
剪邮票
如【图1.jpg】, 有12张连在一起的12生肖的邮票。
现在你要从中剪下5张来,要求必须是连着的。
(仅仅连接一个角不算相连)
比如,【图2.jpg】,【图3.jpg】中,粉红色所示部分就是合格的剪取。
请你计算,一共有多少种不同的剪取方法。
请填写表示方案数目的整数。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。
按顺序的图1-3
二、代码
package Lan2016;public class G减邮票 {/*有12张连在一起的12生肖的邮票。现在你要从中剪下5张来,要求必须是连着的。仅仅连接一个角不算相连)粉红色所示部分就是合格的剪取。请你计算,一共有多少种不同的剪取方法这仅仅是部分题目因为没有图*//** 大致思路:我们五层for循环遍历每一个邮票,并找到5个符合条件的* 对于像网格、迷宫之类的问题,我们采用深度优先遍历的思想,将每一个格子遍历,但是不会重复的遍历** *///1.定义数组来存放这些格子,定义一个计数器,用来存最后的减去方法个数,定义用来表示格子数static boolean[] arr = new boolean[13];//定义为boolean类型,表示是被选中,还是不选中,有两种情况//数组的长度为13,因为从1到12 表示12张邮票,下标0没有被使用static int count;static int n;//2.主函数public static void main(String args[]){//五层for循环遍历每一个方格,从1到12for(int x1 = 1; x1 <= 12; x1++){for(int x2 = x1 + 1; x2 <= 12; x2 ++){for(int x3 = x2 + 1; x3 <=12; x3 ++){for(int x4 = x3 + 1; x4 <= 12; x4 ++){for(int x5 =x4+1; x5 <=12;x5 ++){//将所选中的格子赋值为true,表示被选中arr[x1] = arr[x2] =arr[x3]=arr[x4]=arr[x5]=true;n=0;//调用dfs方法,来找这五个格子dfs(x1);//传入i的原因是因为,从树或图的根节点开始向下遍历//如果n=5,表示选好了,计数器加一if(n == 5){count++;}arr[x1] = arr[x2] =arr[x3]=arr[x4]=arr[x5]=false;//看当前的5个各自是否符合条件后,需要将数组都赋值false,便于下一次的遍历}}}}}System.out.println(count);//输出计数器}//定义dfs函数static void dfs(int m){//要写参数//因为循环的时候我们把数组中的某些的元素已经赋值为true//对于找到的目前的格子,我们赋值为falsearr[m] = false;n++;//找到一个格子,将格子数加一//判断当前节点的左边一个节点是否被访问过,如果没有被访问,则去访问if(m != 1 && m != 5 && m != 9 && arr[m-1])dfs(m-1);//访问当前节点的右边一个节点是否被访问,如果没访问,则去访问if(m != 4 && m!= 8 && m != 12 && arr[m+1])dfs(m+1);//访问当前节点的上一个节点是否被访问,如果没访问,则去访问if(m != 1 && m != 2 && m != 3 && m != 4 && arr[m-4])dfs(m-4);//访问当前节点的上一个节点,如果没有被访问,则去访问if(m != 9 && m != 10 && m != 11 && m != 12 && arr[m + 4])dfs(m+4);}}
三、反思
1.for循环用来找到五个不同的格子,并赋值true,每次找之前都要将n(找到的不相邻的方格数)都要赋值为0,便于我们重新找的时候,给n++,n=5的时候说明已经找到,
2.dfs是为了找到这不相邻的五个格子,从当前的格子往 上下左右去找相邻的格子,当是ture的时候,表明这是我们for循环里选过的,我们赋值false,并n++,再从相邻的格子递归找下去,若找到的正是我们选过的,那么n就等于5,我们count++