《编程之美——微软技术面试心得》一摞烙饼的排序初体验
生活随笔
收集整理的這篇文章主要介紹了
《编程之美——微软技术面试心得》一摞烙饼的排序初体验
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
《編程之美》讀書筆記:1.3?一摞烙餅的排序
問題:
????星期五的晚上,一幫同事在希格瑪大廈附近的“硬盤酒吧”多喝了幾杯。程序員多喝了幾杯之后談什么呢?自然是算法問題。有個(gè)同事說:“我以前在餐館打工,顧客經(jīng)常點(diǎn)非常多的烙餅。店里的餅大小不一,我習(xí)慣在到達(dá)顧客飯桌前,把一摞餅按照大小次序擺好——小的在上面,大的在下面。由于我一只手托著盤子,只好用另一只手,一次抓住最上面的幾塊餅,把它們上下顛倒個(gè)個(gè)兒,反復(fù)幾次之后,這摞烙餅就排好序了。我后來想,這實(shí)際上是個(gè)有趣的排序問題:假設(shè)有n塊大小不一的烙餅,那最少要翻幾次,才能達(dá)到最后大小有序的結(jié)果呢?”
你能否寫出一個(gè)程序,對于n塊大小不一的烙餅,輸出最優(yōu)化的翻餅過程呢?
初步分析:
1、使用動態(tài)規(guī)劃來解決,然而不能很快找出狀態(tài)轉(zhuǎn)移方程,暫時(shí)放棄。 2、從上到下,從上往下確定當(dāng)前序列的有序程度(升序、降序),當(dāng)遇到違背有序的程度的元素的時(shí)候, 判斷該元素是否在這個(gè)有序序列區(qū)間范圍, 1)若在這個(gè)有序序列區(qū)間范圍,則將該違背有序元素和有序序列一起翻轉(zhuǎn) 2)若不在這個(gè)有序序列范圍,則將違背有序元素上面的有序序列進(jìn)行翻轉(zhuǎn) 3)當(dāng)該元素與序列邊界元素相同,則判斷該元素下一個(gè)元素以確定序列類型 舉例子: 輸入樣例: 5? 5 2 3 7 1 樣例分析: 從上往下分析5->2當(dāng)前序列是降序的,邊界范圍是[5,2],當(dāng)遇到3的時(shí)候,發(fā)現(xiàn)違背當(dāng)前有序類型(降序),并且3在這個(gè)有序序列中,所以翻轉(zhuǎn)這個(gè)有序序列和這個(gè)元素,得出 3 2 5 7 1 從頭再次判斷該序列,評估該序列有序類型3->2(降序),邊界范圍是[3,2],當(dāng)遇到5的時(shí)候,發(fā)現(xiàn)違背當(dāng)前有序類型(降序),因?yàn)?span style="background-color:rgb(255,255,0)">5不在這個(gè)有序序列,所以將違背有序元素上面的有序序列進(jìn)行翻轉(zhuǎn),得出 2 3 5 7 1 從頭再次判斷該序列,評估該序列有序類型3->7(升序),邊界范圍[3,7],當(dāng)遇到1的時(shí)候,發(fā)現(xiàn)違背當(dāng)前有序類型(降序),因?yàn)?不在這個(gè)有序序列,所以將違背有序元素上面的有序序列進(jìn)行翻轉(zhuǎn),得出 7 5 3 2 1 從頭再次判斷該序列,評估該序列有序類型7->1(降序),但是題目要求序列最終有序類型是升序,所以整個(gè)序列再次翻轉(zhuǎn)一次,得出 1 2 3 5 7 /* 把一摞餅按照大小次序擺好——從小到大,小在上,大在下 只能用一只手,一次抓住最上面的幾塊餅,把他們上下顛倒個(gè)個(gè)兒, 反復(fù)幾次之后,排好序 假設(shè)有n塊大小不一的烙餅,最少翻轉(zhuǎn)幾次,才能達(dá)到大小有序的結(jié)果? */ #define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <algorithm> #include <vector> using namespace std; void printData(int val) {cout << val << " "; } void init_bin(vector<int> &v) {int n;//需要排序的餅的數(shù)目cin >> n;for (int i = 0; i < n; i++){int a;cin >> a;v.push_back(a);} }void sort_bin(vector<int> &v) {while (1){bool flag ;//排序標(biāo)記int pStart = 1;//默認(rèn)開始遍歷的下標(biāo)為2if (v[1] == v[0]){while (v[pStart] == v[pStart - 1] && pStart < v.size())pStart++;//若元素相同,則判斷下一個(gè)}flag = v[pStart]>v[pStart - 1];//確定當(dāng)前排序類型(升序、降序)bool next = flag;for (int i = pStart + 1; i < v.size(); i++){while (v[i] == v[i - 1] && i < v.size())i++;next = v[i]>v[i - 1];//確定當(dāng)前元素與上一個(gè)比較后是升序還是降序if (next==flag)//與原本序列違背continue;auto _Start = &v[0];int *_End;//while (v[i] == v[0] && i < v.size())i++;if (flag ==v[i] > v[0]&& v[i] != v[0]){_End = &v[i];}else{_End = &v[i - 1];}reverse(_Start, _End+1);for_each(v.begin(), v.end(), printData); cout << endl;break;}//forif (next==flag&&flag)break;else if (next == flag&&flag == false){reverse(v.begin(), v.end());for_each(v.begin(), v.end(), printData); cout << endl;}}//while }int main(void) {vector<int> v;init_bin(v);sort_bin(v);cout << endl;system("pause");return 0; }
存在問題: 只分析上方有序程度,但是該序列其他部分有序程度并沒有分析 比如 10 3 2 1 6 5 4 9 8 7 0 這個(gè)樣例就存在著部分區(qū)域有序的現(xiàn)象,[3,1] [6,4] [9,7][0],而這種情況的話,上述程序在6的時(shí)候已經(jīng)分析錯(cuò)誤了,要修改,請大神指教。
總結(jié)
以上是生活随笔為你收集整理的《编程之美——微软技术面试心得》一摞烙饼的排序初体验的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JRE和JDK的解释及区别
- 下一篇: 海阔凭鱼跃 天高任鸟飞-大上海,人人都向