zoukankan      html  css  js  c++  java
  • java求微信最强连一连(方法:递归回溯遍历)

    package my_mian_shi;
    
    
    
    /**
     * 
     * 
     * 
     * @author Administrator
     *
     */
    public class GameMain {
    	
    	class TwoInteger{
    		public Integer column;
    		public Integer row;
    	}
    	
    	boolean noFullPath=true;//判断是否 没有找到全路径
    	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.noFullPath=false;
    		}
    		//左边是否可以走
    		if (this.noFullPath
    				&&!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.noFullPath
    				&&!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.noFullPath
    				&&!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.noFullPath
    				&&!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(5,6,new int[] {3,4,5,26,21}) ; 
    
    	 	/*
    	 	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, 13);//设置入口
    	 	gm.run(0);
    	 	gm.showPath();
    	}
    }
    

    稍微优化一下的代码

    package my_mian_shi;
    
    
    
    /**
     * 
     * @author Administrator
     *
     */
    public class GameMain {
    	
    	boolean noFullPath=true;//判断是否 没有找到全路径
    	Integer column;   //列
    	Integer row;   //行
    	int []notExistPot;  //不能存在的点
    	boolean [] passedPot; //已经经过的点(以二维的方式表示某个方格)
    	Integer []path; //点的路径( 每一个数值表示 从左到右、从上到下、从0开始、给方块编号 )
    	
    	
     	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为true和path
     	public void setPassedPotAndPath(int p,int a) {
     		setPassedPotAndPath(p,a,true);
     	}
    
     	
     	//判断是否在边界(组合)
     	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 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) {
    		return this.passedPot[pot];
    	}
    	
    	//判断点是否是不存在的点或者已经过的点
    	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.noFullPath=false;
    		}
    		//左边是否可以走
    		if (this.noFullPath
    				&&!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.noFullPath
    				&&!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.noFullPath
    				&&!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.noFullPath
    				&&!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.passedPot[a]=b;
    	}
    
    	public static void main(String[] args) {
    	 	GameMain gm = new GameMain(5,6,new int[] {0,6,28,22,16}) ; 
    	 	gm.setPassedPotAndPath(0, 8);//设置入口
    	 	
    	 	Long start = System.currentTimeMillis();
    	 	
    	 	gm.run(0);
    	 	gm.showPath();
    	 	
    	 	Long stop = System.currentTimeMillis();
    	 	System.out.println();
    	 	System.out.println((stop-start)+"毫秒");
    	}
    }
    
  • 相关阅读:
    考研复试之dp重温
    面试总结
    决策树学习记录
    python机器学习随笔
    大三狗重新复习算法之递推
    第十二届CSP总结
    unity(Exploder插件)研究
    unity学习笔记2
    Unity3d学习笔记(持续更新)。。。
    4.24
  • 原文地址:https://www.cnblogs.com/math-and-it/p/9898869.html
Copyright © 2011-2022 走看看