日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

两道有趣的面试题

發(fā)布時間:2025/7/25 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 两道有趣的面试题 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

?

?

題目一

竹筒有20根簽,10根白色,10根紅色。抽取10根顏色一致可獲得100元獎勵,抽取9根顏色一致可獲得50元獎勵,但是抽取紅色5根白色5根就損失50元,問這游戲是否值得參與?原因?

?

這是典型的組合數求期望問題。設事件‘抽取10根顏色一致’為A,事件‘抽取9根顏色一致’為B,事件‘抽取紅色5根白色5根‘為C。

根據組合數公式

C(m.n) = m!/(n!*(m-n)!)

求得事件A的概率P(A) =?C(10,10)*2/C(20,10) =?0.00001082508822446903 ;

  事件B的概率P(B) =?C(10,9)*C(10,1)*2/C(20,10) =?0.001082508822446903;

  事件C的概率P(C) =?C(10,5)*C(10,5)/C(20,10) =?0.34371820130334063;

?

期望 =?P(A)*100 + P(B)*50+P(C)*(-50) =?-17.130702115222242;

結論,期望低于0。游戲無數次后,最終會虧損17.13元,該游戲不值得玩。

?

?

下面我們使用程序實現該游戲,并且提供求期望的函數。

?

第一個思考,如何高效求出概率,

第二個思考,如何有效地模擬用戶抽簽的情況,

第三個思考,如何統(tǒng)計抽簽結果呢,

。。。。。

最后想想,萬一日后用戶需要修改游戲規(guī)則呢

?

完成整個模擬,需要實現四個模塊:

第一部分,制定游戲規(guī)則和獎勵規(guī)則

第二部分,計算期待

第三部分,獲取一次游戲結果

第四部分,根據獎勵規(guī)則,統(tǒng)計結果

?

打代碼總是很愉快地,啦啦啦~~~

?

1 function Probability(){ 2 3 //--------------------1,制定規(guī)則 4 5 //抽獎箱中的包含的簽種類和數量 6 this.typeColor = { 7 'red': 10, 8 'white':10 9 }; 10 //抽取數量 11 this.extractNum = 10; 12 //可能性,和收益對應表 13 this.possibility = { 14 '10' : 100, 15 '9' : 50, 16 '5' : -50 17 }, 18 19 20 //--------------------2,計算期待 21 this.getExpectation = function(){ 22 23 //暫時省略這一部分代碼,下面我們一同探討這一部分代碼如何優(yōu)化 24 return (-17.130702115222242).toFixed(2); 25 }; 26 //-------------------3,獲取一次游戲結果 27 this.playGame = function(){ 28 var _a = [] ;//空抽獎箱,存儲所有的球 29 var _r = []; //‘抽獎結果’ 30 for( a in this.typeColor){ 31 for(var i=0;i<this.typeColor[a];i++){ 32 _a.push(a); 33 } 34 }//將簽放入抽獎箱 35 36 37 //遍歷,開始抽獎, 38 for(var i=0;i<10;i++){ 39 //抽取特定一個球 40 var _i = Math.round(Math.random()*(_a.length-1)); 41 //將抽出的球,放入‘抽獎結果’中 42 _r.push(_a[_i]); 43 //移除抽獎箱中剛被抽取的球 44 _a.splice(_i,1); 45 } 46 return _r; 47 }; 48 49 //-------------------4,統(tǒng)計結果 50 this.getResult = function(arr){ 51 //統(tǒng)計各種球的結果 52 var _r = {}; 53 for( k in arr){ 54 _r[arr[k]]? _r[arr[k]]++:_r[arr[k]] = 1; 55 } 56 57 //統(tǒng)計收益 58 for(p in _r){ 59 for(k in this.possibility){ 60 if(_r[p] == k){ 61 _r.earnings = this.possibility[k];//價格 62 } 63 } 64 } 65 return _r; 66 } 67 } 考慮代碼重用性,可以動態(tài)修改規(guī)則

?

下面我們一起思考求期望這一部分如何逐步優(yōu)化:

?

嘗試一,只完成基本的題目要求

?

1 function probability1(){ 2 //通用C函數 3 //C(m.n) = m!/(n!*(m-n)!) 4 function C(a,b){ 5 var _n=1,_d=1;//分子,分母 6 for(var i=a;i>0;i--) 7 _n *=i; 8 for(var i=b;i>0;i--) 9 _d *=i; 10 for(var i=1,j=(a-b);j>0;i++,j--) 11 _d *= i; 12 return _n/_d; 13 } 14 return C(10,10)*2/C(20,10)*100+//抽取10根相同顏色的概率*100 15 C(10,9)*C(10,1)*2/C(20,10)*50+//抽取9根相同顏色的概率*50 16 C(10,5)*C(10,5)/C(20,10)*(-50);//抽取5根相同顏色的概率*(-50) 17 18 }

?

仔細觀察,好多組合數是被重復計算的,例如,C(10,10)和C(20,10)等等,可否用一個變量存儲已經計算過的組合數,下次求相同的組合數的時候可以從靜態(tài)變量中獲取而不需要重復計算。

?

?

嘗試二,在嘗試一的基礎上避免計算重復的C

?

1 function probability2(){ 2 //通用C函數 3 function C(a,b){ 4 var _n=1,_d=1; 5 if(!resOfC[a+','+b]){ 6 var _n=1,_d=1;//分子,分母 7 for(var i=a;i>0;i--) 8 _n *=i; 9 for(var i=b;i>0;i--) 10 _d *=i; 11 for(var i=1,j=(a-b);j>0;i++,j--) 12 _d *= i; 13 return _n/_d; 14 15 }else{ 16 return resOfC[a+','+b]; 17 } 18 } 19 20 var resOfC = {}; //一個新的臨時數組,存儲可能出現的結果 21 //如果之前計算過C(10,10),可以直接從 22 console.info(C(10,10)*2/C(20,10)); 23 console.info(C(10,9)*C(10,1)*2/C(20,10)); 24 console.info(C(10,5)*C(10,5)/C(20,10)); 25 return C(10,10)*2/C(20,10)*100+ 26 C(10,9)*C(10,1)*2/C(20,10)*50+ 27 C(10,5)*C(10,5)/C(20,10)*(-50); 28 29 }

?

然而,判斷組合數是否重復計算并不是重點。有數學公式C(m,n) = C(m,m-n),我們計算C(10,9)可以轉換為計算C(10,1),以提高計算效率。

?

?

嘗試三,在嘗試一的基礎上判斷a/2和b的大小,例如對于C(10,9),直接計算C(10,1)

?

1 function probability3(){ 2 //通用C函數 3 function C(a,b){ 4 var _n=1,_d=1;//分子,分母 5 6 if(b>a/2) 7 b = a-b; 8 9 for(var i=a;i>0;i--) 10 _n *=i; 11 for(var i=b;i>0;i--) 12 _d *=i; 13 for(var i=1,j=(a-b);j>0;i++,j--) 14 _d *= i; 15 return _n/_d; 16 } 17 18 var resOfC = {}; //一個新的臨時數組,存儲可能出現的結果 19 //如果之前計算過C(10,10),可以直接從 20 return C(10,10)*2/C(20,10)*100+ 21 C(10,9)*C(10,1)*2/C(20,10)*50+ 22 C(10,5)*C(10,5)/C(20,10)*(-50); 23 24 }

?

學過組合數的同學都知道,有數學公式C(n,k)=C(n-1,k)+C(n-1,k-1) ,?

我們先從C(0,0)算起,然后C(1,0),C(1,1),C(2,0),C(2,1),C(2,2)......C(n,k),仔細觀察,其實求組合數的問題由交疊的子問題構成。

第一時間想到的是使用遞歸關系包含子問題和大問題具有的相同形式,但由于子問題具有交疊,用遞歸方法解決代價很大,我們可以考慮使用動態(tài)規(guī)劃來求解。

?

對每個交疊的子問題只求解一次,并把結果存儲在記錄表中,最后得出原始問題的解。

?

?

嘗試四,利用遞歸和動態(tài)規(guī)劃來求解組合數

?存在C(n,k)=C(n-1,k)+C(n-1,k-1) ?,建立一張表,我們對數據進行動態(tài)更新,即每一次迭代,我們都去根據公式計算出合適的值。

1 function probability3(){ 2 //C(a,b)=C(a-1,b-1)+C(a-1,b) 3 //通用C函數 4 function C(a,b){ 5 if(b==0){ 6 return 1; 7 } 8 var temp = [];// 9 for (var i = 0; i < a; i++) { 10 temp[i] = []; 11 temp[i][0] = 1;//每行首尾為1 12 temp[i][i+1] = 1;//每行末尾為1 13 14 for (var j=1;j<=i;j++) { 15 temp[i][j] =temp[i-1][j-1]+temp[i-1][j];////計算第i行第j列的值 16 } 17 } 18 return temp[a-1][b]; 19 } 20 return C(10,10)*2/C(20,10)*100+ 21 C(10,9)*C(10,1)*2/C(20,10)*50+ 22 C(10,5)*C(10,5)/C(20,10)*(-50); 23 }

?

源碼及游戲演示測試地址:http://lovermap.sinaapp.com/probability.html

效果圖:

?

?

題目二

眼前有兩塊100px*100px的兩塊div,分別距離我們10m和7m,但是由于視覺差,我們只看到最靠近我們的一塊板。用鼠標模擬我們的運動軌跡,鼠標右移類似于我們往右側行走。請模擬實現我們右移,所看到兩塊div形態(tài)變換。

?

一開始,我腦海中的構想:

?

假設100px=4cm,即半徑等于85cm=>2125px。由于時間的關系,就直接把草稿拍照放上來,雅蠛蝶,真的好復雜:

?

?

我們圍繞小圈圈,想看到后面的div。在我們接近圓邊東方這個點的過程中,前面的div將會不要斷縮小,而后面的div將會不斷放大。但是鼠標移動npx,而div會放大mpx,需要集合詳細的三角函數和反三角函數計算。好啦沒問題來了,怎么算D1和D2

?于是我開始不斷惡補各種高中三角知識。。。。。

?

先補一下三角函數的基礎知識

?再補充一下javascript關于三角函數的方法

  Math.cos(x)?X的余弦函數??
  Math.sin(x)?X的正弦函數??
  Math.tan(x)?X的正切函數??
  Math.acos(y)?X的反余弦函數??
  Math.asin(y)?X的反正弦函數??
  Math.atan(y)?X的反正切函數

折騰大半個晚上了,為什么還算不出來,難道真的是我理解錯了 ?好咯好咯~~重新再想想

?秉承“怎么簡單怎么算”的原則,我重新理解了一次題目。。。。

10米和7米這兩個數值如果轉換為像素將不利于計算,出來的效果也不太樂觀,我將它們分別改成了10cm和7cm了。

?

?

嗯嗯,應該是這樣子了

?

?假設人行走a cm,我們可以通過a來表示D1和D2的長度,期間使用到相似三角形、三角形面積公式等原理,完全不需要三角函數和反三角函數。剩下的就不難了

1 var $ = function(id){ 2 return typeof id == 'string' ? document.getElementById(id) : id; 3 }; 4 //計算前面板初始寬度 5 $("box1").style.width = 28/Math.sqrt(65)*30+'px'; 6 (function(o){ 7 if(o){var o = $(o);}else{return false;}; 8 var d = document,x,y; 9 o.onselectstart = function(){return false;}; 10 o.onmousedown = function(e){ 11 e = e || window.event; 12 x = e.clientX-o.offsetLeft; 13 d.onmousemove = function(e){ 14 e = e || window.event; 15 var a = e.clientX - x; 16 17 //小圓點在虛線范圍內可拖拽 18 if(a>=0 && a<90){ 19 o.style.left = e.clientX - x + "px"; 20 var Div1 = 28/Math.sqrt(65+8*a); 21 var Div2 = (9/7)*a/Math.sqrt((9/49)*a*a+9); 22 $("box1").style.width = Div1*30+'px'; 23 $("box2").style.width = Div2*30+'px'; 24 } 25 26 }; 27 d.onmouseup = function(){ d.onmousemove = null; }; 28 }; 29 })('origin');

?

源碼及演示地址:http://lovermap.sinaapp.com/rotate.html

?

?

拖動小黑點->拖動小黑點->

?

?

?

總結

第一點,面試前千萬不要熬夜,千萬不要熬夜,千萬不要熬夜!!!重要的事情要說三遍,面試答題的時候,腦袋滿滿的困意和餓意,將會造成悲慘的結局。

第二點,注意要把問題細化,著手解決問題前,應該根據題目所給的條件,將問題拆分成為若干小問題,然后針對性地根據逐一解決。

第三點,避免先入為主。一開始認為問題很難,不斷深究,最后很容易把自己逼得走投無路。當問題暫時無法解決的時候,回到最初的問題,重新分析,換一個角度,將會有新想法。

?

參考鏈接

動態(tài)規(guī)劃:http://baike.baidu.com/link?url=SqUecaUxZ92jblJIsVjAkrXILHxrvSeTYmUWB9TPYMCnWHvBJwvmvTteh_UUlNImL-p1yDt_XbLWk3znmIJCGa

js反三角函數:http://baike.baidu.com/link?url=v1cRFdqMdkWQTamUJEjXB9ge7T5i7Cd0avM76EpORk53u7T1Uy-jpzbyuC0Rrb1Fjv3hrlhjjQKGAzq6MPVVFq

轉載于:https://www.cnblogs.com/0603ljx/p/4820235.html

《新程序員》:云原生和全面數字化實踐50位技術專家共同創(chuàng)作,文字、視頻、音頻交互閱讀

總結

以上是生活随笔為你收集整理的两道有趣的面试题的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。