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

雁過無痕

  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),這兩個表達式只要計算一個就可以。

 

⑵ 另一種剪枝方法:額外記錄每次計算最靠后的那個數的位置。比如位置順序:abc、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個數計算有可能無解。顯然在無解時,采用盡可能多的剪枝方法,必然會極大的提高性能。

 

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

 

書上的解法二實現



下面的代碼是個半成品:




#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>
            国产精品视频大全| 亚洲国产日韩欧美一区二区三区| 欧美日韩国产一区| 亚洲电影免费观看高清完整版在线 | 国产精品成人aaaaa网站| 国产一区二区三区网站| 亚洲欧美中文日韩在线| 日韩亚洲成人av在线| 欧美黄色小视频| 久久久久久一区| 国产综合婷婷| 久久综合狠狠综合久久激情| 西西人体一区二区| 国产亚洲综合性久久久影院| 亚洲欧美激情视频| 亚洲一级高清| 国产日产欧产精品推荐色| 欧美专区日韩专区| 欧美影院成人| 亚洲第一精品福利| 亚洲大胆人体在线| 欧美精品99| 亚洲性图久久| 午夜精品美女久久久久av福利| 国产乱人伦精品一区二区| 亚洲欧美日韩久久精品| 亚洲欧美韩国| 国产综合视频在线观看| 欧美成人一二三| 欧美激情国产高清| 亚洲视频一区二区| 亚洲欧美国内爽妇网| 精品成人国产在线观看男人呻吟| 另类综合日韩欧美亚洲| 欧美成人午夜激情视频| 99精品福利视频| 亚洲视频香蕉人妖| 黄色成人在线网站| 91久久精品视频| 国产伦精品一区二区三区| 免费日韩av电影| 欧美日韩成人| 久久久久成人精品免费播放动漫| 老司机一区二区| 亚洲一区二区三区影院| 久久国产精品亚洲77777| 亚洲精品你懂的| 亚洲欧美国产不卡| 亚洲精品视频二区| 亚洲欧美伊人| 亚洲国产精品一区| 亚洲综合视频网| 亚洲片区在线| 午夜视频在线观看一区二区| 91久久久久| 欧美亚洲免费电影| 99视频有精品| 久久婷婷激情| 欧美一区1区三区3区公司| 欧美91福利在线观看| 欧美一区二区大片| 欧美精品一区二区三区在线播放 | 激情欧美一区二区| 亚洲欧美视频一区| 另类尿喷潮videofree| 亚洲欧美另类国产| 欧美顶级少妇做爰| 久久一本综合频道| 国产精品―色哟哟| 日韩视频免费在线观看| 亚洲国产精品视频| 久久久久se| 亚欧美中日韩视频| 欧美日韩一级大片网址| 亚洲第一页在线| 伊人久久av导航| 亚洲欧美日韩一区二区| 亚洲一区美女视频在线观看免费| 欧美激情乱人伦| 欧美刺激性大交免费视频| 国产日韩一区二区三区在线| 99国产成+人+综合+亚洲欧美| 亚洲精品国精品久久99热一| 久久久久欧美精品| 久久影视精品| 狠狠操狠狠色综合网| 午夜欧美精品久久久久久久| 亚洲尤物影院| 国产精品高潮久久| 一区二区三区色| 亚洲综合色自拍一区| 欧美色精品在线视频| 日韩视频一区| 亚洲欧美国产视频| 国产精品一区二区在线观看不卡 | 欧美刺激性大交免费视频| 美女性感视频久久久| 狠狠爱综合网| 久久另类ts人妖一区二区| 免费不卡欧美自拍视频| 亚洲大片av| 欧美福利网址| 日韩午夜电影| 亚洲欧美激情视频| 国产午夜精品福利| 久久久久欧美精品| 亚洲福利视频三区| 一区二区三区免费观看| 欧美偷拍一区二区| 亚洲欧美一区二区三区极速播放| 久久不见久久见免费视频1| 国自产拍偷拍福利精品免费一| 久久久不卡网国产精品一区| 亚洲电影在线观看| 亚洲视频在线观看视频| 国产酒店精品激情| 久久综合五月| 亚洲免费av片| 性欧美精品高清| 在线观看日韩av电影| 欧美激情第4页| 亚洲视频在线观看一区| 久久久一本精品99久久精品66| 亚洲高清激情| 欧美午夜不卡视频| 久久精品30| 日韩视频免费观看高清完整版| 亚洲综合另类| 亚洲国产成人在线播放| 欧美日韩视频在线第一区| 欧美亚洲日本一区| 91久久综合| 亚洲国产一区在线| 欧美视频免费看| 欧美中文字幕在线视频| 亚洲国产精品精华液网站| 午夜国产精品影院在线观看| 国内精品一区二区| 欧美日韩国产影院| 久久国产88| 99精品欧美| 欧美顶级艳妇交换群宴| 午夜精品美女自拍福到在线 | 亚洲香蕉视频| 在线观看亚洲| 国产精品日日做人人爱| 欧美高清不卡| 欧美一区二区日韩一区二区| 亚洲激情午夜| 久久美女艺术照精彩视频福利播放| 日韩视频永久免费| 国产一区二区三区高清在线观看| 欧美日韩国产丝袜另类| 久久综合狠狠| 性色一区二区三区| aa国产精品| 亚洲精品国产品国语在线app | 蜜臀va亚洲va欧美va天堂 | 亚洲国产精品久久久久秋霞影院| 国产精品欧美久久久久无广告| 蜜桃久久av| 久热精品视频| 久久久精品久久久久| 亚洲欧洲99久久| 亚洲深夜影院| 亚洲特级毛片| 亚洲香蕉网站| 亚洲一区国产视频| 亚洲一区二区三区四区视频| 亚洲精品美女在线观看| 亚洲国产福利在线| 亚洲黑丝一区二区| 欧美激情久久久久| 欧美激情成人在线视频| 欧美福利视频网站| 欧美二区不卡| 亚洲激情小视频| 亚洲精品一区二区网址| 亚洲国产日韩在线| 亚洲精华国产欧美| 亚洲经典视频在线观看| 欧美激情欧美狂野欧美精品| 欧美va亚洲va国产综合| 欧美11—12娇小xxxx| 欧美电影免费观看高清完整版| 免费亚洲网站| 亚洲福利在线观看| 亚洲人午夜精品免费| 亚洲人成网站777色婷婷| 亚洲精品国产精品乱码不99按摩 | 亚洲观看高清完整版在线观看| 欧美电影打屁股sp| 亚洲第一中文字幕| 日韩视频在线播放| 在线视频亚洲一区| 欧美一二三区在线观看| 久久米奇亚洲| 欧美精品在线观看91| 欧美性开放视频| 国产一区二区三区高清在线观看|