《编程之美——微软技术面试心得》一摞烙饼的排序初体验
生活随笔
收集整理的這篇文章主要介紹了
《编程之美——微软技术面试心得》一摞烙饼的排序初体验
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
《編程之美》讀書筆記:1.3?一摞烙餅的排序
問題:
????星期五的晚上,一幫同事在希格瑪大廈附近的“硬盤酒吧”多喝了幾杯。程序員多喝了幾杯之后談什么呢?自然是算法問題。有個同事說:“我以前在餐館打工,顧客經常點非常多的烙餅。店里的餅大小不一,我習慣在到達顧客飯桌前,把一摞餅按照大小次序擺好——小的在上面,大的在下面。由于我一只手托著盤子,只好用另一只手,一次抓住最上面的幾塊餅,把它們上下顛倒個個兒,反復幾次之后,這摞烙餅就排好序了。我后來想,這實際上是個有趣的排序問題:假設有n塊大小不一的烙餅,那最少要翻幾次,才能達到最后大小有序的結果呢?”
你能否寫出一個程序,對于n塊大小不一的烙餅,輸出最優化的翻餅過程呢?
初步分析:
1、使用動態規劃來解決,然而不能很快找出狀態轉移方程,暫時放棄。 2、從上到下,從上往下確定當前序列的有序程度(升序、降序),當遇到違背有序的程度的元素的時候, 判斷該元素是否在這個有序序列區間范圍, 1)若在這個有序序列區間范圍,則將該違背有序元素和有序序列一起翻轉 2)若不在這個有序序列范圍,則將違背有序元素上面的有序序列進行翻轉 3)當該元素與序列邊界元素相同,則判斷該元素下一個元素以確定序列類型 舉例子: 輸入樣例: 5? 5 2 3 7 1 樣例分析: 從上往下分析5->2當前序列是降序的,邊界范圍是[5,2],當遇到3的時候,發現違背當前有序類型(降序),并且3在這個有序序列中,所以翻轉這個有序序列和這個元素,得出 3 2 5 7 1 從頭再次判斷該序列,評估該序列有序類型3->2(降序),邊界范圍是[3,2],當遇到5的時候,發現違背當前有序類型(降序),因為5不在這個有序序列,所以將違背有序元素上面的有序序列進行翻轉,得出 2 3 5 7 1 從頭再次判斷該序列,評估該序列有序類型3->7(升序),邊界范圍[3,7],當遇到1的時候,發現違背當前有序類型(降序),因為1不在這個有序序列,所以將違背有序元素上面的有序序列進行翻轉,得出 7 5 3 2 1 從頭再次判斷該序列,評估該序列有序類型7->1(降序),但是題目要求序列最終有序類型是升序,所以整個序列再次翻轉一次,得出 1 2 3 5 7 /* 把一摞餅按照大小次序擺好——從小到大,小在上,大在下 只能用一只手,一次抓住最上面的幾塊餅,把他們上下顛倒個個兒, 反復幾次之后,排好序 假設有n塊大小不一的烙餅,最少翻轉幾次,才能達到大小有序的結果? */ #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;//需要排序的餅的數目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 ;//排序標記int pStart = 1;//默認開始遍歷的下標為2if (v[1] == v[0]){while (v[pStart] == v[pStart - 1] && pStart < v.size())pStart++;//若元素相同,則判斷下一個}flag = v[pStart]>v[pStart - 1];//確定當前排序類型(升序、降序)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];//確定當前元素與上一個比較后是升序還是降序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 這個樣例就存在著部分區域有序的現象,[3,1] [6,4] [9,7][0],而這種情況的話,上述程序在6的時候已經分析錯誤了,要修改,請大神指教。
總結
以上是生活随笔為你收集整理的《编程之美——微软技术面试心得》一摞烙饼的排序初体验的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JRE和JDK的解释及区别
- 下一篇: 海阔凭鱼跃 天高任鸟飞-大上海,人人都向