wangflood

          精心維護(hù)一個(gè)技術(shù)blog,為了工作,也是愛(ài)好。

            BlogJava :: 首頁(yè) :: 聯(lián)系 :: 聚合  :: 管理
            14 Posts :: 19 Stories :: 8 Comments :: 0 Trackbacks
          前些日子在群里討論,有一個(gè)哥們出一道題:5,6,7,8,9,10按順序插入+-*/和括號(hào),得到結(jié)果2000.
          大家的先沉默了一會(huì),二分鐘后,有人說(shuō)這題沒(méi)意思。呵呵。口算還是有點(diǎn)難的。于是我說(shuō),可以寫(xiě)個(gè)程序試一試。結(jié)果,花了三個(gè)小時(shí),寫(xiě)完了
          import java.util.HashSet;
          import java.util.Iterator;
          import java.util.Set;

          /**
           * 
          @author Sam Wang
           * 
          @since Mar 22, 2011
           
          */
          public class Demo {

              
          public static void main(String[] args) {

                  
          double[] arr = { 5678910 };
                  
          double[] arrTemp = null;
                  
          int random = 0;
                  
          double last = 0;
                  StringBuffer sb 
          = null;
                  Set
          <String> results = new HashSet<String>();

                  
          for (int i = 0; i < 100000; i++) {
                      arrTemp 
          = arr.clone();
                      shuffle(arrTemp);
                      sb 
          = new StringBuffer();
                      sb.append(arrTemp[
          0]);
                      
          for (int j = 1; j < arrTemp.length; j++) {
                          random 
          = (int) (Math.random() * 4);
                          
          switch (random) {
                          
          case 0:
                              sb.append(
          "+").append(arrTemp[j]);
                              arrTemp[j] 
          = arrTemp[j - 1+ arrTemp[j];
                              
          break;
                          
          case 1:
                              sb.append(
          "-").append(arrTemp[j]);
                              arrTemp[j] 
          = arrTemp[j - 1- arrTemp[j];
                              
          break;
                          
          case 2:
                              sb.append(
          "*").append(arrTemp[j]);
                              arrTemp[j] 
          = arrTemp[j - 1* arrTemp[j];
                              
          break;
                          
          case 3:
                              sb.append(
          "/").append(arrTemp[j]);
                              arrTemp[j] 
          = arrTemp[j - 1/ arrTemp[j];
                              
          break;

                          
          default:
                              
          break;
                          }
                      }

                      last 
          = arrTemp[arrTemp.length - 1];
                      System.out.println(last);
                      
          if (last == 2000) {
                          sb.append(
          "=2000");
                          results.add(sb.toString());
                      }
                  }

                  
          for (Iterator<String> it = results.iterator(); it.hasNext();) {
                      String item 
          = it.next();
                      System.out.println(item);

                  }
              }

              
          /**
               * 
          @param arrTemp
               * 
          @return void 打亂數(shù)組元素順序。
               
          */
              
          private static void shuffle(double[] arrTemp) {
                  
          int index = 0;

                  
          for (int i = 0; i < arrTemp.length; i++) {
                      index 
          = (int) (Math.random() * arrTemp.length);
                      swap(arrTemp, i, index);
                  }
              }

              
          /**
               * 
          @param arrTemp
               * 
          @param i
               * 
          @param index
               *            交換數(shù)據(jù)元素
               
          */
              
          private static void swap(double[] arrTemp, int i, int index) {
                  
          double temp = arrTemp[i];
                  arrTemp[i] 
          = arrTemp[index];
                  arrTemp[index] 
          = temp;
              }

          }
          有兩個(gè)技巧:在不確定是+-*/哪種情況下,可以random一下,多for幾次,那么這幾種情況大致上可以照顧到。
                                ()在算法里面的體現(xiàn)是,使用()我發(fā)現(xiàn),數(shù)字的前后順序可以混亂。打印出結(jié)果不行的話再刪除不遲。
          打印結(jié)果:
          9.0*8.0-7.0*6.0+10.0*5.0=2000
          8.0*9.0-7.0*6.0+10.0*5.0=2000
          7.0*8.0+9.0*6.0+10.0*5.0=2000
          打印出來(lái)的效果不太好,我組織一下:
          5*(6*(-7+8*9)+10)=2000;
          5*(6*(7*8+9)+10)=2000;
          如果,不允許取負(fù)數(shù)的話,當(dāng)然就只有一個(gè)結(jié)果了。

          有點(diǎn)疑惑,為什么Collection.shuffle()可以,Array.shuffle()卻不提供。

          當(dāng)然,算法肯定有可以改進(jìn)的地方。



          posted on 2011-03-29 12:31 wangflood 閱讀(369) 評(píng)論(1)  編輯  收藏

          Feedback

          # re: 56789+-*/() 2000 2011-03-30 13:12 wangflood
          趙靖 5:47:53 AM
          這題用逆波蘭(后綴)式再枚舉即可,然后轉(zhuǎn)化為帶括號(hào)的中綴式
          趙靖 5:48:17 AM
          就可以繞過(guò)括號(hào),這樣就變成一道體力活了
          蕎葉 5:52:07 AM
          哈哈。
          蕎葉 5:52:49 AM
          那晚,我寫(xiě)了三個(gè)小時(shí)。
          趙靖 5:53:27 AM
          完全做出來(lái)三個(gè)小時(shí)不算多,但是有正確的方向要堅(jiān)定的多
          趙靖 5:54:51 AM
          數(shù)字是排定的,符號(hào)插入其中,再構(gòu)造圖求路徑的話就更清晰了
          蕎葉 5:55:04 AM
          http://www.aygfsteel.com/wangflood/articles/Demo.html
          蕎葉 5:55:06 AM
          呵呵。
          趙靖 5:56:39 AM
          這樣做法可能是錯(cuò)誤的,設(shè)想如果(5+6)*(7+8)+9+10這個(gè)順序是shuffle不出來(lái)的
          趙靖 5:57:21 AM
          后綴應(yīng)為56+78+*9+10+
          趙靖 5:57:46 AM
          要去掉括號(hào),后綴是一個(gè)絕佳的選擇
          蕎葉 5:58:01 AM
          不允許56這樣的組合。
          趙靖 5:58:13 AM
          我寫(xiě)的是后綴式
          蕎葉 5:58:18 AM
          shuffle是把[5,6,7,8,9,10]的前后順序弄亂。
          蕎葉 5:58:27 AM
          發(fā)來(lái)看看啊。
          蕎葉 5:58:35 AM
          不懂后綴式是什么意思。、
          趙靖 5:58:52 AM
          逆波蘭式呀
          趙靖 5:59:08 AM
          就是后根遍歷表達(dá)式
          趙靖 6:01:35 AM
          看看你的程序能不能找到184
          蕎葉 6:02:03 AM
          為什么要找到184
          趙靖 6:02:20 AM
          這個(gè)說(shuō)明你shuffle是不能表達(dá)括號(hào)的優(yōu)先級(jí)的
          蕎葉 6:03:48 AM
          shuffle,比括號(hào)得到了更多的結(jié)果。
          蕎葉 6:03:59 AM
          但括號(hào)可以做到的,shuffle都給辦到。
          趙靖 6:04:31 AM
          你怎么表達(dá)這種括號(hào)呢(5+6)*(7+8)
          趙靖 6:04:52 AM
          shuffle 去掉括號(hào)看看
          蕎葉 6:05:22 AM
          對(duì)噢。
          蕎葉 6:06:35 AM
          可以這樣,5+6)*(7+8)
          算出5+6后,就是[11,7,8,9,10]再次shuffle
          趙靖 6:06:51 AM
          那算法也太猥瑣了些
          蕎葉 6:06:56 AM
          哈哈。就期望能算出第二個(gè)結(jié)果來(lái)。
          蕎葉 6:06:59 AM
          我也這么覺(jué)得啊。
          趙靖 6:09:47 AM
          這個(gè)式子的通用格式是

          5678910
          abcdef
          然后吧abcde查到合適的位置去,其中至少f是最后面的
          如56+67+*8+9+10+就表達(dá)了(5+6)*(7+8)+9+10
          趙靖 6:10:19 AM
          后綴計(jì)算是最快的,僅僅需要一個(gè)棧
            回復(fù)  更多評(píng)論
            


          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 重庆市| 呼玛县| 来凤县| 湖南省| 海伦市| 新乡县| 淳化县| 启东市| 当阳市| 扎囊县| 西乌珠穆沁旗| 临江市| 大安市| 宽甸| 鲁甸县| 云阳县| 获嘉县| 沧源| 泸州市| 盱眙县| 包头市| 呼图壁县| 监利县| 留坝县| 开封县| 桦甸市| 夹江县| 积石山| 南投市| 绥宁县| 凌源市| 抚顺县| 博湖县| 岳阳市| 渝北区| 和田市| 萨迦县| 山东| 岗巴县| 甘谷县| 赤城县|