青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

雁過無痕

  C++博客 :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::

《編程之美》讀書筆記22:    1.16  24點游戲

給定4個數,能否只通過加減乘除計算得到24?由于只有4個數,弄個多重循環,就可以。如果要推廣到n個數,有兩種思路:

采用前綴/后綴表達式。相當于將n個數用n-1個括號括起來,其數目就是一個catlan數。最多可得到 f(n) = (1/n * (2*n - 2)! / (n-1)! / (n-1)!) * n! * 4^(n-1) = 4^(n-1) * (2*n-2)! / (n-1)! 種表達式,當n=4時,共可得到 7680種。

n個數中任意抽取2個,進行計算最多有6種結果,將計算結果放回去,再從剩下的n-1個任取2個,進行計算,如此反復,直到只剩下1個數。按這種算法,共要處理表達式:g(n)=(n*(n-1)/2*6) * ((n-1)*(n-2)/2*6) * ((n-2)*(n-3)/2*6) * (2*1/2*6) = n!*(n-1)!*3^(n-1)n=4時,最多要處理3888種。 (書上的代碼將這兩種思路混在一塊了。)

f(n) / g(n) = (4/3)^(n-1) * (2*n-2)! / n! / (n-1)! / (n-1)!

很明顯,當n比較大時(比如n大于8),會有 f(n) < g(n)。比如:f(10)/g(10)=0.178。

f(n)g(n)的比值,可以看出,這兩種解法都存在大量的不必要計算。當n比較大時,思路2的冗余計算已經嚴重影響了性能。要如何減少這些不必要計算呢?

可以記錄得到某個計算結果時所進行操作。比如: ab、cd4個數取前2個,進行加法計算得到 a+b,則記錄‘+’。另外,假設加減號的優先級為0,乘除號的優先級為1。

ab進行減/除計算時,實際上得到 a-bb-aa/bb/a

當取出2個數ab,進行計算,這兩個數上次的操作符有下面這幾種情況:

都為空:

要計算6個結果,即 a+b, a-b, b-a, a*b, a/b, b/a。

 

只有一個為空:假設: a = a1 op1 a2

   ⑴ 一種剪枝方法是: op1為減(除)號,則不進行加減(乘除)計算。

       因為: (a-b)-c可以轉為a-(b+c),這兩個表達式只要計算一個就可以。

 

⑵ 另一種剪枝方法:額外記錄每次計算最靠后的那個數的位置。比如位置順序:a、bc、d,進行a+c計算時,記錄了c位置,再與數b計算時,由于b位置在c位置前,不允許計算 (a+c) + b (a+c) – b這樣就避免了表達式 a+b+c a-b+c被重復計算。

 

都不為空: 假設: a = a1 op1 a2, b= b1 op2 b2

   要計算的結果: a op3 b = a1 op1 a2op3 (b1 op2 b2)

   ⑴ 如果 op1 op2的優先級相同,那么 op3 的優先級不能與它們相同,若相同,則原來的表達式可以轉為 ((a1 op4 a2) op5 b1) op6 b2,因而沒必要對原來的表達式進行計算。比如 (m1+m2)(m3-m4)之間只進行乘除計算,而不進行加減計算。

⑵ 如果 op1 op2的優先級不同,那么 op3 無論怎么取,其優先級都必會與其中一個相同,則原表達式可以轉化((c1 op4 c2) op5 c3) op6 c4這種形式,因而該表達式沒必要計算。如(m1+m2)(m3*m4),不進行任何計算。

總之:op1 op2優先級不同時,不進行計算。

         op1 op2優先級相同時,進行計算的操作符優先級不與它們相同。

 

要注意的是:剪枝不一定提高性能(在筆記1.3 一摞烙餅的排序 中已經說明了這個問題)。如果n個數計算可得到24,過多的避免冗余計算,有可能嚴重降低性能。計算n=6時,碰到一個組合,僅使用了③的剪枝方法,得到結果時處理了四百個表達式,但再采用了②的第一種剪枝方法,處理的表達式達到五十三萬多。(也許②的第二種剪枝方法不存在這么嚴重的問題。)與烙餅排序不同的是,烙餅排序總能找到一個結果,而n個數計算有可能無解。顯然在無解時,采用盡可能多的剪枝方法,必然會極大的提高性能。

 

另外,對于輸出表達式,書上的程序進行了大量的字符串操作,實際上可以只記錄,每一步取出的兩個數的位置(即記錄i、j值),在需要輸出時,再根據所記錄的位置,進行相應的字符串操作就可以了。

 

書上的解法二實現



下面的代碼是個半成品:




#include
<iostream>
#include
<sstream>
#include
<cmath>
using namespace std;

const double Result = 24;
const size_t Cards = 6;
double number[Cards]={11,21,31,41,51,61};
char op[Cards+1= {0};
size_t pos[Cards];

static long long count1=0;
static long long count2=0;
static bool calc(size_t step);

inline 
bool calc2(size_t step, size_t i, double na, double nb, char op9)
{
  op[i] 
= op9;
  
switch (op9) {
    
case '+':   number[i] = na + nb; break;
    
case '-':   number[i] = na - nb; break;
    
case '*':   number[i] = na * nb; break;
    
case '/':   number[i] = na / nb; break;
    
default : break;
  }

  
return calc(step-1);
}


inline 
bool iszero(double num)
{
  
const double Zero = 1e-9
  
if (num > Zero || num < -1.0 * Zero) return false
  
return true;
}


size_t getop(
const char op9)
{
  
static size_t arr[256]= {0}
  arr[
'+']=1,arr['-']=1,arr['*']=4,arr['/']=4;
  
return arr[(size_t)op9];
}



bool calc(size_t step)
{
  
++count1;
  
if (step <= 1{
    
++count2;   
    
if (fabs(number[0- Result)<1e-6{
      
return true
    }
  
    
return false;
  }
 
  
for(size_t i = 0; i < step; i++){
    
for(size_t j = i + 1; j < step; j++{
      
double na = number[i];
      
double nb = number[j];
      unsigned 
char op1=op[i];
      unsigned 
char op2=op[j];
      op[j] 
= op[step - 1];
      number[j] 
= number[step - 1];
      
bool ba=true, bb=true;
      size_t v
=getop(op1)+getop(op2);
      
      
if (v==5) ba=bb=false;
      
else if (v==2) ba=false;
      
else if (v==8) bb=false;
      
// else if (v==1 || v==4) {
        
// unsigned char ch2= op1 + op2;      
        
// if (ch2=='-') ba=false;
        
// else if (ch2=='/') bb=false;
      
// } 
    
       
      
//if (v==5) ba=bb=false;
      
// else if (((v-1)&v)==0) { //case: 1 2 4 8
        
// if (v==2) ba=false;
        
// else if (v==8) bb=false;
        
// else {
          
// unsigned char ch2= op1 | op2;      
          
// if (ch2=='-') ba=false;
          
// else if (ch2=='/') bb=false;          
        
// }   
      
// }   
      
      
//if (1) ba=bb=true;         
      if (ba) {
        
if (calc2(step, i, na, nb, '+')) return true;
        
if (calc2(step, i, na, nb, '-')) return true;
        
if (calc2(step, i, nb, na, '-')) return true;
      }

      
if (bb) {
        
if (calc2(step, i, na, nb, '*')) return true;
        
if (! iszero(nb) && calc2(step, i,na, nb, '/')) return true;
        
if (! iszero(na) && calc2(step, i,nb, na, '/')) return true
      }
 
     
      number[i] 
= na;
      number[j] 
= nb;
      op[i] 
= op1;
      op[j] 
= op2;     
    }

  }

  
return false;
}


int main()
{
  
for (size_t i=0; i<Cards; ++i) pos[i]=i;
  cout
<< calc(Cards)<<endl;
  cout
<< count1<<"  "<<count2<<endl; 
}


posted on 2010-08-01 22:50 flyinghearts 閱讀(1033) 評論(0)  編輯 收藏 引用 所屬分類: 編程之美 、C++
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲精品专区| 久久久精品网| 一本久久青青| 日韩网站在线观看| 一区电影在线观看| 亚洲一区二区三区免费在线观看 | 欧美国产日韩精品| 欧美电影免费| 欧美性事在线| 国产一区二区精品久久99| 一区二区三区黄色| 亚洲欧美国产va在线影院| 亚洲愉拍自拍另类高清精品| 先锋a资源在线看亚洲| 久久久久久97三级| 欧美精品成人一区二区在线观看 | 欧美国产日韩一区二区| 欧美日韩精品免费观看视频| 国产精品毛片大码女人| 亚洲电影网站| 亚洲免费视频观看| 欧美成人精品不卡视频在线观看| 亚洲日本欧美在线| 99视频精品在线| 久久久另类综合| 国产精品成人v| 91久久在线播放| 欧美一区二区黄色| 亚洲欧洲三级| 欧美中文字幕视频在线观看| 欧美精品1区2区| 伊人狠狠色j香婷婷综合| 亚洲天堂av高清| 欧美福利一区二区三区| 久久综合综合久久综合| 日韩视频三区| 久久久久久久综合日本| 国产精品久久久久久久午夜片| 亚洲国产一成人久久精品| 欧美中日韩免费视频| 日韩一区二区高清| 欧美黑人国产人伦爽爽爽| 国产一区二区三区网站| 亚洲在线免费视频| 亚洲破处大片| 美女成人午夜| 在线精品一区| 久久综合精品一区| 国产精品99久久久久久久久| 一区二区三区高清不卡| 久久精品国产999大香线蕉| 久久久精品一区| 亚洲日韩欧美视频一区| 久久视频一区| 精品99一区二区| 久久精品国产清高在天天线| 一区二区三区成人精品| 欧美另类视频在线| 亚洲精品日韩欧美| 亚洲第一狼人社区| 久热精品视频在线| 91久久精品国产91久久性色tv| 亚洲欧美日本国产专区一区| 欧美在线视频网站| 制服丝袜激情欧洲亚洲| 欧美精品乱人伦久久久久久| 99精品国产高清一区二区| 久久综合久久美利坚合众国| 久久久蜜臀国产一区二区| 极品少妇一区二区三区| 久久精品一级爱片| 亚洲新中文字幕| 欧美日韩在线一区| 亚洲尤物影院| 亚洲一区综合| 国产一区二区三区在线观看网站 | 国产伦精品一区二区三区高清| 亚洲欧美日韩国产综合精品二区 | 亚洲欧美国产精品va在线观看 | 妖精成人www高清在线观看| 欧美日韩视频第一区| 亚洲影院色无极综合| 欧美一区二区性| 亚洲国产精品一区二区尤物区 | 免费视频一区| 一区二区三区日韩精品| 一区二区三区高清| 国产自产女人91一区在线观看| 老鸭窝91久久精品色噜噜导演| 美女精品国产| 亚洲欧美日韩综合aⅴ视频| 香蕉成人啪国产精品视频综合网| 亚洲国产精品黑人久久久 | 欧美1区免费| 欧美视频在线不卡| 可以看av的网站久久看| 欧美激情亚洲自拍| 久久国产精品久久久| 欧美成人一区二区三区在线观看 | 久久久久久久久久看片| 亚洲精品一级| 欧美影院在线播放| 日韩一本二本av| 欧美一区二区黄色| 一区二区三区日韩精品| 久久精品亚洲一区二区| 在线亚洲美日韩| 久久阴道视频| 久久久久88色偷偷免费| 欧美精品一区二区三区在线看午夜| 国产精品久久久久毛片软件| 免费在线观看日韩欧美| 欧美午夜一区二区| 亚洲黄色免费| 伊人久久噜噜噜躁狠狠躁| 亚洲免费在线观看视频| 一区二区三区四区蜜桃| 久久久久久久网| 欧美在线观看天堂一区二区三区| 欧美大片va欧美在线播放| 久久三级视频| 国产午夜精品在线| 亚洲一卡二卡三卡四卡五卡| 亚洲精品美女| 欧美成年人视频网站| 快播亚洲色图| 黄色成人av网站| 欧美一级视频| 久久国产66| 国产欧美在线播放| 亚洲在线观看免费| 亚洲综合二区| 国产精品初高中精品久久| 亚洲精品日日夜夜| 一级成人国产| 欧美视频中文一区二区三区在线观看| 亚洲激情国产| 亚洲最新视频在线播放| 欧美日韩国产综合久久| 99v久久综合狠狠综合久久| 亚洲视频视频在线| 国产伦精品一区二区三区高清 | 亚洲欧美变态国产另类| 欧美日韩亚洲不卡| 中文亚洲免费| 欧美在线观看一区二区| 国产在线拍揄自揄视频不卡99| 亚洲欧美成人| 久久躁狠狠躁夜夜爽| 亚洲福利国产| 欧美破处大片在线视频| 亚洲午夜激情网站| 久久精品视频在线免费观看| 国产一区二区看久久| 久久免费视频一区| 亚洲国产一区在线观看| 99视频一区二区| 国产精品乱码人人做人人爱| 午夜精品久久久久久久99樱桃| 久久久久久999| 亚洲精品乱码久久久久久蜜桃91 | 欧美在线视频观看免费网站| 久久精品国产亚洲高清剧情介绍| 国产亚洲人成a一在线v站| 久久久久久久一区| 亚洲毛片网站| 久久成人亚洲| 亚洲欧洲精品天堂一级| 欧美伦理a级免费电影| 亚洲欧美日韩精品久久亚洲区| 久久综合九色综合久99| 亚洲剧情一区二区| 国产伦精品一区二区三区| 免费成人网www| 亚洲欧美区自拍先锋| 亚洲精品久久视频| 国产精品一区二区三区四区| 久久一区激情| 亚洲素人在线| 亚洲高清激情| 久久av老司机精品网站导航| 亚洲欧洲在线观看| 国产欧美精品一区| 欧美激情中文字幕乱码免费| 亚洲欧洲99久久| 亚洲激情亚洲| 玖玖综合伊人| 久久狠狠婷婷| 亚洲影院色无极综合| 亚洲日本理论电影| 国内久久婷婷综合| 国产精品电影网站| 欧美精品一区二区三区蜜臀 | 久久精品91久久香蕉加勒比| 91久久国产综合久久| 久久福利精品| 香蕉乱码成人久久天堂爱免费| 日韩午夜电影| 亚洲激情欧美| 亚洲电影中文字幕|