程式設計之美 微軟技面心得

2021-06-27 04:52:23 字數 4104 閱讀 2311

搜尋演算法,運用餘數優化

lcd (x, y) = ( if x&1 && y&1:  lcd(x, (x-y)/2);   else  lcd(x/2 if x&1==0, y/2 if y&1==0) )

x=x1x2..xi . y1y2...yj(z1 z2... zk)  =/10^j + m/10^j

其中 迴圈節 m = z1 z2 ... zk/ (10^k -1)

所以 x = [+  / (10^k -1)  ] /10^j =

[  *(10^k -1) +]/ [(10^k -1)*(10^j ) ], 化簡就可。

反向: 給出 n,m 求 n/m的迴圈節:

n/m = k + 0.y1y2...yj(z1 z2... zk)

t/m = 0.y1y2...yj(z1 z2... zk) = y/10^j + z/ [ 10^j *(10^k - 1) ]

乙個重要的結論是0.(z1z2...zk) = /(10^k-1),  比如 0.(353) =  353/(1000-1) = 353/999.

2  給定a1~ak,以及推導公式ak+1 <= a1~ak,最快的辦法求到 an

方法:矩陣加速(專用於求解k階遞推數列) 或 特徵方程(會存在無理數)

二分(  按照縱線二分)

轉化為帶物品數量限制的揹包重量問題 , o(n^2*sum),n=obj_cnt, sum=w_total

//bool[i][j]: 裝i個物品,能否裝到重量j

bool[0][0] = true

for k=1 to obj_cnt: //揹包問題最外層迭代一定是物品,因為物品只能裝一次

for i=1 to obj_cnt/2:

for j = w_total to obj_w[k]:

bool[i][j] = bool[i-1][j] || bool[i-1][j-obj_w[k]] 

5 最短摘要的生成

6 桶中取黑白球算概率:

排列組合 + dp(類似還有卡特蘭數f [ 2n ] = e( f[ 2n-2*i-2 ] * f[ 2*i ], i=0~n-1 ) =  c(2n, n) - c(2n, n-1) )

cnt[sum][white]為還剩下sum個球,白球數量white的概率排列組合數。

cnt[200][100] = 1

cnt[sum][white] = cnt[sum+1] [ white ]*3 + cnt[sum+1] [ white+2]   //四種取法,對應四種上乙個狀態

最後 cnt[1][0] / (cnt[1][0] + cnt[1][1])

int a[21][21];

memset(a, 0, sizeof(a));

a[20][10]=1;

for(int i=19; i>=1; i--)

}cout<

還有一種方法: 白球的數量每輪減少0 或2, 所以白球數量始終是偶數,如果只剩乙個球,則必定是黑球。

7 螞蟻爬桿

找所有螞蟻都離開桿子的最短和最長時間。呵呵,簡單轉化一下就變成同時求最大最小值了。

8 取石子遊戲數學推導

帶狀態壓縮(二進位制,表示第幾個數被用到)的dp

s[ bits ] = map< result, cnt > // bits 表示哪些數字被用到, result表示計算結果, cnt表示得到該結果的方法數

inline int calc(int tt, int a, int op, int b, bool & tag)

switch(op)

return a/b;}}

tag= false; return 0;

}bool 24game(vector&num)}}

}}}}

return s[15][24] > 0;

}

10 數字啞謎和回文

啞謎: 數學推理

回文: 列舉「我」和寺,很快能夠 找到人過大佛四*我 = 是佛。的所有解

he^2 = she, 類似, (10*h +e )^2 = h^2*100 + e^2 + 20*h*e = s*100 + 10*h + e, 則 e^2 %10 = e, e = 1、5、6、0

e = 1:    1 + 20h + 100h^2 = 1 + 10h + 100s, 10h = 100(s-h^2), h = 10(s-h^2), s=h^2, h=0, s=0 不行

e = 5....

10 俄羅斯方塊

二進位制表示塊

11 掃雷

12 數獨

方法一: dp  

value[ volume ] [ obj_i ] 表示對obj_i飲料物品分組進行裝包,得到的最大滿意度

value[ volume ] [ obj_i ] = max ( value[volume - k* w[i] ] [ obj_i - 1] + v[i] * k, k = 0 ~ c[i] ) 即對重量為volume狀態,輪番使用分組中的物品

for i = 1 to n://分組

for volume=max_volume to k*w[i]://每個重量

for k = 1 to c[i]://每個分組物品

value[ volume ] [ obj_i ] = max ( value[volume - k* w[i] ] [ obj_i - 1] + v[i] * k //上乙個分組遞推到本分組

或者:for i = 1 to n://分組

for k = 1 to c[i]://每個分組物品

for volume=max_volume to k*w[i]://每個重量

value[ volume ] [ obj_i ] = max ( value[volume - k* w[i] ] [ obj_i - 1] + v[i] * k

方法二:記憶化搜尋(dfs+dp)

一些不需要用到的狀態就不用算了

方法三: 貪心法

考慮到 max_volume 是乙個二進位制的數, 那麼每次從最低位找,找到可以用於填充這一位的飲料 

比如第 j(j>=0)位, 對應於可以用的飲料為 ( w=2^k,  value=xx ),其中k<=j

根據貪心策略找到最好的、這一位可用的飲料。使用 2^(j-k)單位 。

14 光影切割問題

根據交點個數,能夠推導直線分割的面數, 即cnt(0)=1, cnt (n) = cnt(n-k) + k+1 , cnt(n) = e(ki) + n=交點個數+n+1

所以o(n^2) 列舉獲得所有交點。o(mlogm)為對交點排序。

另外,可以使用逆序對個數來算交點

如直線跟兩邊的邊框縱線相交,如線1在兩條邊框上交點分別為(y1=1, y2=10),而另乙個線為(y1=10, y2=1),那麼他們有乙個逆序對,也必有乙個交點。

這道題直覺上可以greedy,但其實不行,必須states dynamic planning

cnt[y1][y2][y3][y4][y5] 表示各種書分別為y1,y2..y5,其中y1>=y2>=y3>=y4>=y5,的最大折扣數

這個dp存在乙個優化:

對任意狀態cnt[y1][y2][y3][y4][y5] ,後續除了<[1,2,3],4,5>一定存在

<[1 2 3] 4>這種含有4而不含5的放書方法, 

同理後續除了<[1,2],3,4>一定存在

<[1,2] 3>這種含有3不含4的方法

所以遞推公式變得簡單了:cnt[y1][y2][y3][y4][y5]  = max( cnt[y1-1][y2-1][y3-1][y4-1][y5-1]  if(y5>=1),  cnt[y1-1][y2-1][y3-1][y4-1][y5]  if(y4>=1),  cnt[y1-1][y2-1][y3-1][y4][y5] if(y3>=1)。。。, cnt[y1-1][y2][y3][y4][y5] if(y1>=1) ). 

第一章:

1  繪製cpu佔用率曲線

程式設計之美 微軟技術面試心得

內容介紹 第1章 遊戲之樂 遊戲中碰到的題目.1 1.1 讓cpu佔用率曲線聽你指揮.3 1.2 中國象棋將帥問題.13 1.3 一摞烙餅的排序.20 1.4 買書問題.30 1.5 快速找出故障機器.35 1.6 飲料供貨.40 1.7 光影切割問題.45 1.8 小飛的電梯排程演算法.50 1....

微軟程式設計之美 初賽

相似字串對於兩個長度相等的字串,我們定義其距離為對應位置不同的字元數量,同時我們認為距離越近的字串越相似。例如,0123 和 0000 的距離為 3,0123 和 0213 的距離則為 2,所以與 0000 相比,0213 和 0123 最相似。現在給定兩個字串 s1 和 s2,其中 s2 的長度不...

程式設計之美閱讀心得

3.30 我的結論是 1 如果存在乙個對a的安全狀態t,那麼如果t 能夠在一步轉為t,則t 是a的必敗狀態。2 此題的思路的關鍵是確定一種a的必勝的模式 比如分偶數堆,每堆個數相同。其實思路應該更簡單一些,就是對m分情況討論,如果m是偶數,如何分堆必勝 兩堆,個數相等。3 對m為奇數的情況,還沒有想...