最近在准备CCF,所以一并把算法也一起复习了一下。下面的题目是老师让我们按照回溯法书上的模板写的题,纪录一下。
我太菜辽,呜呜呜。
package com.lianup.suanfa.Backtrack;
/**
*题目:小明从n*n矩阵的左下方走到右上方,并且不能够走过矩阵从右到左的对角线的上方,每次只能向上或者向右走一步
* 求出所有走法
* 要求:按照回溯法的格式写
*/
public class Test2 {
/**
* 用来存放可行解的数组,idnex[layer][0]和index[layer][1]分别表示当解空间深度为layer时的所在坐标
*/
int[][] index;
int n;
int sum;
StringBuilder res;
int[][] gone = new int[][]{{-1,0},{0,1}};
/**
* 启动函数
* @param n
*/
public void cacu(int n){
this.n = n;
index = new int[n*2][2];
index[0][0] = n-1;
index[0][1] = 0;
res = new StringBuilder();
backtrack(1);
}
/**
* 回溯法主函数
* @param layer 当前扩展节点在解空间中的深度
*/
public void backtrack(int layer){
// 此问题回溯法解空间一共有2*n层,因为每个向上和向下走都有走和不走两种选择
if(layer >= 2*n-1){
update();
return;
}
for(int i = 0;i < 2;i++){
// x,y分别为上一次选择后的横纵坐标
int x = index[layer-1][0];
int y = index[layer-1][1];
index[layer][0] = x + gone[i][0];
index[layer][1] = y + gone[i][1];
if(bound(layer)){
backtrack(layer+1);
}
}
}
/**
* 限界函数,判断是否越界
* @param layer
* @return
*/
public boolean bound(int layer){
if(index[layer][0] < 0 || index[layer][0] >= n || index[layer][1] < 0 || index[layer][1] >= n){
return false;
}
if(index[layer][1] < n - index[layer][0] - 1){
return false;
}
return true;
}
/**
* 输出函数
* @return
*/
public String output(){
return res.toString();
}
/**
* 更新函数
*/
public void update(){
sum++;
for(int i = 0;i < n;i++){
res.append(index[i][0] + "," + index[i][1] + " ");
}
res.append("\n");
}
}