java 實現大獅子為A,小獅子為a,大老虎為B,小老虎為b,大狼為C,小狼為c 動物一起過河問題

來源:互聯網
上載者:User

/**
 *
 * @author z84002131
 *  很久很久以前,在一個森林裡,有獅子,老虎和狼,他們應大象的邀請,要到大象家做客。去的路上被一條小河攔住了,需要過河,只有一個獨木舟。現在已知:
 *  1.總共有6隻,分別是獅子爸爸,小獅子,老虎爸爸,小老虎,狼爸爸和小狼。
 *  2.小傢伙們都比較弱小,如果沒有爸爸罩著就會被旁邊的大傢伙吃掉。
 *  3.獨木舟最多能坐2人,無視每隻的大小。
 *  4.大傢伙都會划船,小傢伙裡只有小老虎會划船。
 *  求:安全過河方法。
 *  提示:可以設大獅子為A,小獅子為a,大老虎為B,小老虎為b,大狼為C,小狼為c。再形象的用豎線來表示河,0表示船,那麼題目就是要求畫出
 *  AaBbCc|0  |
 *  ...
 *        |  0|AaBbCc
 *  中間被...省略的步驟
 */

 

import java.util.Vector;

public class AcrossTheRiver {

 private static final int SHIP = 0;
 private static final int LION_A = 1;
 private static final int LION_a = 2;
 private static final int TIGER_B = 3;
 private static final int TIGER_b = 4;
 private static final int WOLF_C = 5;
 private static final int WOLF_c = 6;
 private static final int TOTAL_STATUS = 7;
 
 //用一個整型int來存放當前的狀態,第1位為0表示SHIP在左岸,第1位為1表示SHIP在右岸
 //                             第2位為0表示LION_A在左岸,第2位為1表示LION_A在右岸
 //                             第3位為0表示LION_a在左岸,第3位為1表示LION_a在右岸,往下以此類推
 private static final int BEGIN_STATUS = 0;//初始狀態全都在左岸
 private static final int END_STATUS = 0x7F;//目的是都到右岸去
 private static final int SAILOR = (1 << LION_A) | (1 << TIGER_B) | (1 << TIGER_b) | (1 << WOLF_C);
 private static Vector<Integer> stepVec = new Vector<Integer>();//存放擺渡的步驟,用於最後輸出步驟
   
    //存放每個情境可能的下一步情境
    //考慮到一共有6獸1船共7個物體,每個物體有左岸和右岸兩個狀態,因此一共有2的7次方共128個情境。
    //每個情境的下一步,僅有數種可能的情境:如AaBb|0   |Cc的下一步中,僅有Aa|  0|BbCc和Bb|  0|AaCc這兩個合法的情境
    //利用這張表,可以方便的預測出下一步可能的動作,從而進行推演
 private static Vector<Integer>[] traceMap = createTraceMap();

 //建立traceMap
 private static Vector<Integer>[] createTraceMap(){
  //建立情境表traceMap
  Vector<Integer>[] traceMapTmp = new Vector[1 << TOTAL_STATUS];
  //int iCount = 0;
  for(int i = 0; i < (1 << TOTAL_STATUS); i++){
   traceMapTmp[i] = new Vector<Integer>();
   if(!isStatusLegal(i)){//如果目前狀態不合法就不用再看了
    continue;
   }
   //printStatus(i);
   int statusTmp;
   if(isRight(i, SHIP)){//如果船在右岸
    for(int j = 1; j < TOTAL_STATUS; j++){
     if(isRight(i, j) && isSailor(j)){
      //決定划船的
      statusTmp = setLeft(setLeft(i, SHIP), j);
      if(isStatusLegal(statusTmp)){
       traceMapTmp[i].add(new Integer(statusTmp));
       //iCount++;
       //printStatus(statusTmp);
      }
      //決定是否帶乘客
      int statusTmp2;
      for(int k = 1; k < TOTAL_STATUS; k++){
       if(isRight(statusTmp, k)){
        statusTmp2 = setLeft(statusTmp, k);
        if(isStatusLegal(statusTmp2)){
         traceMapTmp[i].add(new Integer(statusTmp2));
         //iCount++;
         //printStatus(statusTmp2);
        }
       }
      }
     }
    }
   } else {//如果船在左岸
    for(int j = 1; j < TOTAL_STATUS; j++){
     if(!isRight(i, j) && isSailor(j)){
      //決定划船的
      statusTmp = setRight(setRight(i, SHIP), j);
      if(isStatusLegal(statusTmp)){
       traceMapTmp[i].add(new Integer(statusTmp));
       //iCount++;
       //printStatus(statusTmp);
      }
      //決定是否帶乘客
      int statusTmp2;
      for(int k = 1; k < TOTAL_STATUS; k++){
       if(!isRight(statusTmp, k)){
        statusTmp2 = setRight(statusTmp, k);
        if(isStatusLegal(statusTmp2)){
         traceMapTmp[i].add(new Integer(statusTmp2));
         //iCount++;
         //printStatus(statusTmp2);
        }
       }
      }
     }
    }
   }
   //System.out.println("\n");
  }
  //System.out.println("iCount = " + iCount);
  return traceMapTmp;
 }//end of createTraceMap
 
 //擺渡
 private static boolean goTowards(int status){
  //判斷是否勝利了
  if(isSucceed(status)){
   stepVec.add(new Integer(status));
   return true;
  }
  if(stepVec.indexOf(status) == -1){//如果是之前沒遇過的情境,可以繼續走著看看
   stepVec.add(new Integer(status));
  }else{//如果轉回了之前的情境,那就放棄這種走法
   return false;
  }
  for(int i = 0; i < traceMap[status].size(); i++){//窮舉每個可能的下一步情境繼續分析
   if(goTowards(traceMap[status].elementAt(i).intValue())){//遞迴深入 窮舉
    return true;
   }
  }
  stepVec.remove(stepVec.size() - 1);//如果沒找到
  return false;
 }
 
 //判斷勝利條件
 private static boolean isSucceed(int status){
  return (status == END_STATUS) ? true : false;
 }
 //判斷會不會划船的
 private static boolean isSailor(int animal){
  return (SAILOR & (1 << animal)) == (1 << animal);
 }
 //檢查在status狀態下,編號為animal的獸是否在右岸
 private static boolean isRight(int status, int animal){
  return (status & (1 << animal)) == (1 << animal);
 }
 //將某獸移動到左邊
 private static int setLeft(int status, int animal){
  return status & ((~0)^(1 << animal));
 }
 //將某獸移動到右邊
 private static int setRight(int status, int animal){
  return status | (1 << animal);
 }
 
 //判斷當前情況是否有小獸成為犧牲品
 private static boolean isStatusLegal(int status){
  for(int i = 1; i < TOTAL_STATUS; i += 2){
   while(true){
    //如果父子不在同岸
    if(isRight(status, i)  ^ isRight(status, i + 1)){
     //那麼另外兩隻大獸必須和父親在同一邊
     if((isRight(status, (i + 2) % 6) ^ isRight(status, i + 1))
        && (isRight(status, (i + 4) % 6) ^ isRight(status, i + 1))){
      break;
     }
     //否則小獸就掛了
     return false;
     
    //如果父子同岸,那麼有大獸保護,小獸沒問題
    }else {
     break;
    }
   }
  }
  return true;
 }
 
 //列印目前狀態
 private static void printStatus(int status){
  StringBuffer strTmp = new StringBuffer("AaBbCc|0  0|AaBbCc");
  if(isRight(status, SHIP)){
   strTmp.replace(7, 8, " ");
  } else {
   strTmp.replace(10, 11, " ");
  }
  for(int i = 1; i < TOTAL_STATUS; i++){
   if(isRight(status, i)){
    strTmp.replace(i - 1, i, " ");
   } else {
    strTmp.replace(i + 11, i + 12, " ");
   }
  }
  System.out.println(strTmp);
 }
 
 //列印出步驟結果
 private static void showStep(){
  goTowards(BEGIN_STATUS);
  for(int i = 0; i < stepVec.size(); i++){
   printStatus(stepVec.elementAt(i).intValue());
  }
 }
 
 public static void main(String[] args) {
  showStep();
 }
}

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.