java求微信最強連一連(方法:遞歸回溯遍歷)
阿新 • • 發佈:2018-11-02
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); } }