java求微信最强连一连(方法:递归回溯遍历)

package my_mian_shi;



/**
 * 
 * 
 * 
 * @author Administrator
 *
 */
public class GameMain {
	
	class TwoInteger{
		public Integer column;
		public Integer row;
	}
	
	Integer column;   //列
	Integer row;   //行
	int []notExistPot;  //不能存在的点
	boolean [][] passedPot; //已经经过的点(以二维的方式表示某个方格)
	Integer []path; //点的路径( 每一个数值表示 从左到右、从上到下、从0开始、给方块编号 )
	TwoInteger ti = new TwoInteger();//用于进行一维转二维
	
	
 	public GameMain(Integer row,Integer column,int []notEP){
 		
 		this.notExistPot=notEP;
 	 
 		if(column != null && column>0 && row != null && row > 0)
 		{
 			this.column=column;
 	 		this.row=row;
 			passedPot =new boolean[row][column];
 			path = new Integer[row*column-notExistPot.length];
 		}else {
 			throw new RuntimeException("列或行出现问题");
 		}
 
 	}
 	
 	//判断为单一边界
 	public boolean decideSingleBounds(int bounds,int singleBounds) {
 		if((bounds & singleBounds)==0) return false;
 		else return true;
 	}
 	
 	//设置passedPot和path
 	public void setPassedPotAndPath(int p,int a, boolean b) {
 		path[p]=a;//入口
	 	setPassedPot(a, b);
 	}
 	
 	//设置passedPot和path
 	public void setPassedPotAndPath(int p,int a) {
 		path[p]=a;//入口
	 	setPassedPot(a, true);
 	}
 	
	//判断是否在边界(组合) 
 	public int decideBounds(int row ,int column) {
 		int count=0;
 		if(row==0) count += 1;//上边界
 		else if(row==this.row-1) count += 2; // 下边界
 		else if(column==0) count += 4; //左边界
 		else if(column==this.column-1) count += 8; //右边界 
 		return count; 
 	}
 	
 	//判断是否在边界(组合)
 	public int decideBounds(int pot) {
 		int count=0;
 		if (pot<column) count += 1;
 		if ((pot-(row-1)*column)>=0 && (pot-(row-1)*column)<column) count += 2;
 		if (pot%column==0) count += 4;
 		if (pot%column==column-1) return count += 8;
 		return count;
 	}
 	
 	//判断一维到二维数组是否越界
 	public boolean passedPotIndexOutOfBounds(int a) {
 		return a<0 || a>=column*row;
 	}
 	
 	//判断多个数是否存在越界
 	public boolean passedPotIndexOutOfBounds(int []a) {
 		for(int i:a) 
 			if(passedPotIndexOutOfBounds(i))
 				return true;
 		return false;
 	}
 	
 	//二维转一维
 	public int twoToOne(int row,int column) {
 		return (row)*this.column+column;
 	}
 	
 	//一维转二维
 	public void oneToTwo(int pot) {
 		int a=((pot+1)%column)-1;
 		ti.column = (a == -1) ? column-1 : a;
 		ti.row = pot/column;
 		//System.out.println(ti.row+" "+ti.column);
 	}
 	
	//打印路径
	public void showPath() {
		for(int i=0;i<path.length;i++) {
			System.out.print(path[i]+" ");
		}
	}
	
	
	//判断点是否存在
	public boolean notExistPot(Integer pot) {
		for(int i=0;i<notExistPot.length;i++) {
			if(pot==notExistPot[i])
				return true;
		}
		return false;
	}
	
	
	//点是否已经被经过
	public boolean passedPot(Integer pot) {
		oneToTwo(pot);
		return this.passedPot[ti.row][ti.column];
	}
	
	//判断点是否是不存在的点或者已经过的点
	public boolean passedPotOrNotExistPot(int a) {
		return this.notExistPot(a) || this.passedPot(a);
	}
	
	
	// 回溯法遍历 哈密顿通路 的一个解
	public void run(int nowPosition){
		boolean flag=false;
		int a = path[nowPosition];
		if (nowPosition==this.path.length-1) {
			this.showPath();
			System.exit(0);
		}
		//左边是否可以走
		if (!this.decideSingleBounds(this.decideBounds(a), 4) //不能在左边界
				&&!this.passedPotIndexOutOfBounds(a-1)  //不能越界
				&& !this.passedPotOrNotExistPot(a-1)    //不能是已经经过的点和不能是不存在的点
		) {
			this.setPassedPotAndPath(nowPosition+1,a-1);
			run(nowPosition+1);
			flag=true;
		}
		if(flag) {
			setPassedPot(a-1,false);
			flag=false;
		}
		//右边是否可以走
		if(!this.decideSingleBounds(this.decideBounds(a), 8)
				&&!this.passedPotIndexOutOfBounds(a+1) 
				&& !this.passedPotOrNotExistPot(a+1)) {
			this.setPassedPotAndPath(nowPosition+1,a+1);
			run(nowPosition+1);
			flag=true;
		}
		if(flag) {
			setPassedPot(a+1,false);
			flag=false;
		}
		//上边是否可以走
		if(!this.decideSingleBounds(this.decideBounds(a), 1)
				&&!this.passedPotIndexOutOfBounds(a-column)  
				&& !this.passedPotOrNotExistPot(a-column)) {
			this.setPassedPotAndPath(nowPosition+1,a-column);
			run(nowPosition+1);
			flag=true;
		}
		if(flag) {
			setPassedPot(a-column,false);
			flag=false;
		}
		//下边是否可以走
		if(!this.decideSingleBounds(this.decideBounds(a), 2)
				&&!this.passedPotIndexOutOfBounds(a+column)
				&& !this.passedPotOrNotExistPot(a+column)) {
			this.setPassedPotAndPath(nowPosition+1,a+column);
			run(nowPosition+1);
			flag=true;
		}
		if(flag) {
			setPassedPot(a+column,false);
			flag=false;
		}
		
	}
	
	//设置PassedPot的值
	public void setPassedPot(int a, boolean b) {
		this.oneToTwo(a);
		this.passedPot[ti.row][ti.column]=b;
	}

	public static void main(String[] args) {
	 	GameMain gm = new GameMain(9,7,new int[] {4,5,6,11,18,43,56}) ; 
	 	

	 	/*
	 	for(int i=0;i<30;i++) {
	 		System.out.print(i+" ");
	 		gm.oneToTwo(i); // 测试一维转二维
	 	}
	 	*/
	 	/*
	 	for(int i=0;i<30;i++) {
	 		System.out.print(i+" ");
	 		System.out.println(gm.decideBounds(i));//测试边界范围是否正确
	 	}
	 	*/
	 	/*
	 	for(int i=1;i<16;i++) { //测试将组合边界转化为单边界
	 		System.out.print(gm.decideSingleBounds(i, 1)+" ");
	 		System.out.print(gm.decideSingleBounds(i, 2)+" ");
	 		System.out.print(gm.decideSingleBounds(i, 4)+" ");
	 		System.out.print(gm.decideSingleBounds(i, 8)+" ");
	 		System.out.println();
	 	}
	 	*/
	 	/*
	 	for(int i=0;i<5;i++)
	 		for(int j=0;j<6;j++) {
	 			System.out.print(gm.twoToOne(i, j) +" ");
	 		}
	 	*/
	 	gm.setPassedPotAndPath(0, 33);//设置入口
	 	gm.run(0);
	}
}

猜你喜欢

转载自www.cnblogs.com/math-and-it/p/9898869.html