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

Creative Commons License
本Blog采用 知識共享署名-非商業性使用-禁止演繹 3.0 Unported許可協議 進行許可。 —— Fox <游戲人生>

游戲人生

游戲人生 != ( 人生 == 游戲 )
站點遷移至:http://www.yulefox.com。請訂閱本博的朋友將RSS修改為http://feeds.feedburner.com/yulefox
posts - 62, comments - 508, trackbacks - 0, articles - 7

編程之美:一摞烙餅的排序(未完成)

Posted on 2008-04-20 14:59 Fox 閱讀(4051) 評論(13)  編輯 收藏 引用 所屬分類: G游戲編程

Author: Fox

首先聲明:本人沒有解決掉這個問題。

相比第一道讓CPU占用率曲線聽你指揮對Windows系統中CPU占有率概念的考察和對API的使用,以及第二道中國象棋將帥問題對抽象建模的考察。這道題目才算是一道算法題吧?之前那兩道尤其是中國象棋將帥問題總有點腦筋急轉彎的味道。

題目:星期五的晚上,一幫同事在希格瑪大廈附近的“硬盤酒吧”多喝了幾杯。程序員多喝了幾杯之后談什么呢?自然是算法問題。有個同事說:

“我以前在餐館打工,顧客經常點非常多的烙餅。店里的餅大小不一,我習慣在到達顧客飯桌前,把一摞餅按照大小次序擺好——小的在上面,大的在下面。由于我一只手托著盤子,只好用另一只手,一次抓住最上面的幾塊餅,把它們上下顛倒個個兒,反復幾次之后,這摞烙餅就排好序了。

我后來想,這實際上是個有趣的排序問題:假設有n塊大小不一的烙餅,那最少要翻幾次,才能達到最后大小有序的結果呢?

你能否寫出一個程序,對于n塊大小不一的烙餅,輸出最優化的翻餅過程呢?

排序問題是數據結構和算法中比較重要的一個了,之前在一篇被同事成為標題黨的文章中因為提到排序中關于(非)穩定排序的概念還被很多TX鄙視了一番,甚至引來人身攻擊,現在想來都有些后怕。

這道題目一眼看上去最先讓我想到的居然是那道經典的漢諾塔(Tower of Hanoi)問題(當然,漢諾塔不算排序問題)。

1) 相似點★:

a. 都要不斷調整位置,最終實現從小到大排好;

b. 都要借助中間量進行調整。

2) 不同處★:

a. 漢諾塔有多出來的兩根針,翻烙餅只有一只手,明確說明沒有第三只手;

b. 漢諾塔一次只能移動一個,翻烙餅沒限制;

c. 漢諾塔要保證小的始終在上面,翻烙餅沒限制;

d. 漢諾塔移動之前就有序,所以其移動次數是固定的,算法的邏輯也固定(不管是遞歸還是棧操作),翻烙餅沒有這個前提。

3) 把題目用程序語言描述一下吧★:

a. Input : n.

b. Process : generate n random number 0-(n-1), sortting.

c. Output : 0, 1, ..., n-1, and move times num.

4) 存儲結構★★★:

我最開始想到的是:這一摞烙餅其實就是一個雙鏈表,每翻一次相當于將頭節點H與某非頭節點N進行如下變換:

H->next = N->next

N->prior = H->prior = NULL

N->next->prior = H

如果使用普通的雙鏈表,這兒就有一個很明顯的問題,H和N之間的所有節點(如果有的話)的前趨prior和后繼next互換了,對于n比較大的情況,這個操作明顯浪費時間啊(交換前趨prior和后繼next和題目要求的翻幾次似乎也沒有關系吧?只是我作為一個一線的Coder考慮的太具體了)。如果摒棄前趨和后繼的概念,又該怎樣描述呢?

唐朝禪宗大師青原行思曾說:參禪之初,看山是山,看水是水;禪有悟時,看山不是山,看水不是水;禪中徹悟,看山仍然山,看水仍然是水。

俗:日,扯那么多,什么意思?

師:前趨不是前趨,后繼不是后繼。

俗:日,前趨不是前趨,難道是后繼嗎?

師:然也。

Fox:O, my God!整點實際的吧!翻轉一次之后,前趨視為后繼,后繼視為前趨,第奇數次翻轉的前趨是后繼,第偶數次翻轉的后繼是前趨。

整個鏈表的形態如下:

H:Head, F:First, G:F's next, B:C's prior, C:Change, D, C's next, L:Last.

H<==>F<==>G<=...=>B<==>C<==>D<=...=>L

F與C交換的操作如下(Word、PS畫圖),n表示next,p表示prior:

這里只需要修改F、D節點的prior,H、C節點的next,其他節點不變。

后面想了一下,這種方式很難在不添加flag或者對換n、p的情況下正常操作,沒有找到好的方法L,如果你有好的方法不妨告訴我。

最后只好作罷,何苦呢?直接使用數組就完了嘛J!既然是數組,除了翻轉移動麻煩一點,理解和操作還是很容易的。

果然不是搞數學、算法出身的,一上來考慮的就是如何存儲^.^'''',而不是算法本身。

更可笑的是,扯了半天,最后居然還是用數組

5) 算法分析★★★★★:

冒泡排序思想:

最關鍵的是要抽象出隨機數列特征(含當前和移動后數列特征的抽象),并盡量使每一次翻轉有效(所謂有效,即盡量保證每一次操作都向最后的有序靠近而非背離 )。

師:要使大頭在后,應使大頭在后。

俗:日,這是什么狗屁邏輯?

師:因果。在前既是在后。

俗:USA, CNN(操你娘)。

師:翻轉。既不在前,也不在后,使之在前,使之在后。

俗:日,什么東西?既不在前,也不在后,不前不后,難道在中間?。?/p>

師:然也。

Fox:O, my God!整點實際的吧!整個過程分為n輪,在第i(i=0, 1, ..., n-1)輪:

a. 找到大頭n-i,是否有序?是,轉g;

b. 是否大頭在后?是,轉f;

c. 是否大頭在前?是,轉e;

d. 將隊頭(第一個元素)與大頭n-i對調(別忘了是翻轉,中間元素也變序了),++times

e. 將隊頭n-i與第n-i個元素對調,++times

f. ++i,轉a;

g. 輸出序列(0, 1, ..., n)和翻轉次數times;OVER:D。

快速排序思想:

在最開始的時候,我就想到使用快速排序的思想,先使整個數列局部有序,最后調整使全部有序。悲哀的是,在我考慮 4 3 1 2這個數列的時候,我斷定還要通過上面的方式重新像冒泡排序一樣重新來過,立即放棄想法,于是給了上面的思路,而且堅定的認為這個方法已經很好。結果,下午GR告訴我他的反例:4 3 1 2 --> 2 1 3 4|--> 1 2| 3 4,“|”表示從該處翻轉。

我必須承認,這才是好的方法,我過分拘泥于不去改動已經有序的部分。然而,這家伙只知道反駁我,卻無法給出算法。

我只好自己重新考慮局部有序之后的問題。

十分鐘后,我有了如下的答案(目前我能想到的最佳答案),但不得不承認,表述算法比給出一種情況對應的解要麻煩的多的多的多,假定A、B滿足A==B-1,即A、B為相鄰數列(為簡單記,元素和數列統稱數列)。則A、B的組合類型有8種:B(O)A(O)、B(C)A(O)、B(O)A(C)、B(C)A(C)、A(C)B(O)、A(O)B(O)、A(C)B(C)、A(O)B(C),O表示正向(obverse)C表示逆向(reverse),以1 2 3 4為例:

B(O)A(O):3 4 1 2<2>、B(C)A(O):4 3 1 2<4>B(O)A(C):3 4 2 1<5>、B(C)A(C):4 3 2 1<7>;

A(C)B(C):2 1 4 3<1>、A(O)B(C):1 2 4 3<3>A(C)B(O):2 1 3 4<6>、A(O)B(O):1 2 3 4<8>。

對應操作規則如下:

a. 0x0101: B(O)A(O) --> B(C)A(O); 3

b. 0x0001: B(C)A(O) --> A(C)B(O); 2

c. 0x0101: B(O)A(C) --> B(C)A(C);1

d. 0x0000: B(C)A(C):如果當前只剩A、B兩個子列,則翻轉一次成A(O)B(O)1 2 3 4為最終結果,否則,認為B(C)A(C)可以作為一個逆序有序數列考慮,暫時無需翻轉;

e. 0x1010: A(C)B(C) --> A(O)B(C); 3

f. 0x1110: A(O)B(C) --> B(O)A(C);  2

g. 0x1011: A(C)B(O) --> A(O)B(O);1

h. 0x1111: A(O)B(O):A、B可以作為一個有序數列考慮,如果當前只有A、B兩個子列,則正序序列A(O)B(O)1 2 3 4為最終結果。

上面規則的制定其實是反向導出的,遵循的原則是,正序有序的A(O)B(O)和逆序有序的B(C)A(C)可以看作一個序列,A(C)B(O)、B(O)A(C)可一步達到,B(C)A(O)、A(O)B(C)可兩步達到,B(O)A(O)、A(C)B(C)可三步達到。即對于4個元素,最壞的的A(C)B(C)需要4步(對應于上面的冒泡法卻只需要3步L)。而且當元素比較多的時候,記住1、2個有序子列是可行的,但對于完全無序的數列,分析出所有有序子列,既不現實,也無必要。

修改規則如下:隊頭無序&&相鄰數列有序||隊頭有序,翻轉隊頭;否則,將隊頭連同該元素一同翻轉。

由此可見,這算法還要改進:

a. 判斷Array[0]是否正序連續(連續個數nNum1),如果nNum1==n,轉i,如果nNum1!=1,轉c;

b. 判斷Array[0]是否逆序連續(連續個數nNum1),如果nNum1==n,翻轉Array,轉f;

c. 從下標nNum1開始查找Array[0]+1(bObserve = true)和Array[0]-1(bObserve = false)的下標nStart2,如果nNum1==nStart2bOrder1==true,轉e,如果nNum1!=1,置nEnd2=nStart2;

d. 判斷( bObserve == true&&Array[nStart2]+1==Array[nStart2+1] ) || ( bObserve == false&&Array[nStart2]==Array[nStart2+1]+1 ),true則置nEnd2=nStart2,false則置nEnd2=nStart2+1;

e. 翻轉Array[0] to Array[nEnd2],轉a;

f. 輸出Arraytimes。

這樣來看,改進后的算法竟簡單了許多!

不幸的是:按上面給出的算法翻轉合并1 3 5 6 4 8 7 9 2 0:

1 3 5 6 4 8 7 9| 2| 0

2 9 7 8 4 6 5| 3| 1 0

3 5 6| 4| 8 7 9 2 1 0

4 6| 5| 3 8 7 9 2 1 0

5 6| 4 3 8 7 9 2 1 0

6 5 4 3 8| 7| 9 2 1 0

7 8 3 4 5| 6| 9 2 1 0

進入死循環了……

很明顯應該是下面這個樣子:

1 3 5 6 4 8 7 9 2| 0

9 8 7 4 6 5| 3 1 2 0

5 6 4| 7 8 9 3 1 2 0

6 5 4 7| 8 9 3 1 2 0

4 5 6 7 8 9 3| 1 2 0

3 4 5 6 7 8 9 1 2| 0

1 9 8 7 6 5 4 3 2| 0

2 3 4 5 6 7 8 9 1| 0

9 8 7 6 5 4 3 2 1 0|

0 1 2 3 4 5 6 7 8 9

執行9次翻轉。算法如何得到呢?

a. 確定最小無序完整子集SnSn中含n>1個連續數);

b. 將Sn最前面的有序子集Soo>1)加以考慮,一個子集?兩個子集?

______________________________________________________________________________

O, my God!

這個問題,從前天晚上到現在,思考、分析、抽象了至少有15個小時以上了:

a. Apr.18th-19th: 23:00 - 01:30

b. Apr.19th: 11:00 - 13:00

c. Apr.19th-20th: 22:00 - 05:30

d. Apr.20th: 11:00 - 15:00

結果是,到現在無法給出一個最優的翻轉算法。一個周末都花在這上面了,準備放棄L。

LP催著我讓我回學校,是該回去了!

Feedback

# re: 編程之美:一摞烙餅的排序(未完成)  回復  更多評論   

2008-04-21 09:59 by 亨德列克
這個跟那個0、1開關燈問題有點類似,書上有現成的解決方案;具體不記得了,翻下書就有了,LZ可以參考一下?
我是菜鳥,評論……可以忽略……

# re: 編程之美:一摞烙餅的排序(未完成)  回復  更多評論   

2008-04-21 11:25 by yayv
棧排序

從上到下檢查順序, 出現逆序, 就截取,然后順序出棧逆序入棧

如此反復,順序正確之后,判斷最上面是不是最小的,決定最后反轉就是了么

# re: 編程之美:一摞烙餅的排序(未完成)  回復  更多評論   

2008-04-21 20:21 by Fox
這個問題,如果有哪位TX實現了,給個鏈接我去學習一下,如果只是簡單給出分析的話,就未必經得住推敲了……

# re: 編程之美:一摞烙餅的排序(未完成)  回復  更多評論   

2008-04-22 11:11 by kayak
還沒有認真考慮, 不過覺得用程序實現和人工翻轉烙餅其實有一點是很不一樣的.
就是人判斷最大那個烙餅的時間復雜度是O(1), 用眼睛掃一下就可以了, 這點計算機做不到.
所以, 人工翻轉烙餅的時候, 至少可以采用下面這個算法(可能不是最優, 但肯定有效):
1) 找出從上到下的N個烙餅中最大的烙餅.
2) 判斷其是否在最下面, 如果是,到4; 否則到3.
3) 將最大烙餅及其上面的所有烙餅翻轉.
4) 忽略此烙餅(N-1 -> N)
5) 如果N=0, 到6; 否則到1.
6) 結束.

# re: 編程之美:一摞烙餅的排序(未完成)  回復  更多評論   

2008-04-22 12:26 by kayak
3寫錯了, 應該在后面加個3.1.
3.1) 將從上往下N個烙餅翻轉.

# re: 編程之美:一摞烙餅的排序(未完成)  回復  更多評論   

2008-04-22 12:38 by Fox
你這個在我文中給出來了,基于冒泡排序的思想。
次數不能達到最少。

# re: 編程之美:一摞烙餅的排序(未完成)  回復  更多評論   

2008-04-23 12:16 by kayak
我相信不存在一種排序方式, 可以對于任何數據都比其他所有的算法更優.

我想確定一下, 你的目的是
1) 找到一種翻轉算法, 它比任何其他算法"次數"更少的翻轉算法, 或者在大多數情況下次數更少.
2) 對任何一種烙餅分布情況, 找到對于特定于該情型的特定的翻轉方式.

# re: 編程之美:一摞烙餅的排序(未完成)  回復  更多評論   

2008-04-23 17:56 by Fox
我的本意是找一種最優算法,可惜數學基礎太差,對各種算法及其復雜性的計算力不從心……

# re: 編程之美:一摞烙餅的排序(未完成)  回復  更多評論   

2008-04-25 13:14 by Bugs
很有趣!

# re: 編程之美:一摞烙餅的排序(未完成)  回復  更多評論   

2008-04-29 22:41 by HYin
昨天剛買了這本書,學習中呀!

# re: 編程之美:一摞烙餅的排序(未完成)  回復  更多評論   

2008-07-03 21:26 by 我也是想到了漢諾塔啊~~
我也是想到了漢諾塔啊~~

# re: 編程之美:一摞烙餅的排序(未完成)  回復  更多評論   

2011-07-27 12:03 by pzmj
這么簡單的問題,寫了這么多廢話,也算是人才了。。。

# re: 編程之美:一摞烙餅的排序(未完成)  回復  更多評論   

2014-08-30 16:07 by you
U can U up , no can no BB@pzmj
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            99re66热这里只有精品3直播| 很黄很黄激情成人| 夜久久久久久| 99xxxx成人网| 国产精品久久久久久久久久免费| 亚洲一区二区成人| 亚洲欧美日韩天堂| 在线观看一区欧美| 亚洲国产精品电影在线观看| 欧美大片免费| 亚洲欧美在线网| 久久综合给合久久狠狠色| 91久久黄色| 亚洲看片网站| 国语自产精品视频在线看| 亚洲第一页中文字幕| 欧美日韩一区不卡| 久久久久久免费| 亚洲女人小视频在线观看| 美国成人直播| 欧美午夜久久久| 老**午夜毛片一区二区三区| 欧美精品v日韩精品v国产精品 | 国产精品尤物福利片在线观看| 香蕉精品999视频一区二区| 欧美在线观看日本一区| 亚洲天堂av综合网| 久久黄色网页| 亚洲免费在线播放| 狂野欧美一区| 欧美一区二区三区日韩| 男女视频一区二区| 久久国产一区二区| 欧美视频在线一区| 欧美激情一区二区三区全黄| 国产精品美女主播| 亚洲国产乱码最新视频| 国产一区二区精品久久| 在线一区二区日韩| 日韩天天综合| 美日韩精品视频| 久久久久久久999精品视频| 欧美日韩国产成人精品| 欧美黄在线观看| 亚洲成人在线免费| 欧美中文字幕精品| 欧美一区二区三区电影在线观看| 欧美精品国产一区| 亚洲电影免费观看高清完整版| 国产日韩在线亚洲字幕中文| 99riav1国产精品视频| 亚洲精品视频一区| 欧美成人一区二区三区在线观看| 噜噜噜在线观看免费视频日韩| 国产精品毛片| 国产精品99久久久久久人| 亚洲美女啪啪| 欧美日韩系列| 亚洲毛片av在线| 亚洲视频在线观看一区| 欧美精品入口| 亚洲乱码久久| 亚洲视频999| 欧美日韩亚洲一区二区三区在线观看 | 在线一区二区三区做爰视频网站 | 久久综合免费视频影院| 久久久无码精品亚洲日韩按摩| 国产麻豆视频精品| 午夜精品99久久免费| 久久久噜噜噜久噜久久 | 欧美喷潮久久久xxxxx| 亚洲国产视频一区| 99国产精品国产精品久久| 欧美国产日韩a欧美在线观看| 亚洲精品视频在线观看免费| 国产精品美女主播在线观看纯欲| 免费观看30秒视频久久| 欧美成人一区二区在线| 亚洲黄网站黄| 欧美日韩a区| 亚洲深夜福利在线| 久久精品国产综合精品| 国内精品久久久久久| 久久亚洲春色中文字幕久久久| 免费在线亚洲欧美| 亚洲欧洲日本在线| 欧美色123| 欧美一区二区免费| 亚洲激情在线激情| 亚洲欧美三级伦理| 一区二区三区在线不卡| 欧美成人精品不卡视频在线观看| 日韩亚洲国产欧美| 久久精品国产77777蜜臀| 精品成人在线| 欧美三级视频| 久久久久久69| 中日韩午夜理伦电影免费| 久久久久国产免费免费| 99成人免费视频| 黄色成人在线| 国产精品久久久久久五月尺| 久久精品亚洲精品| 亚洲婷婷在线| 亚洲国产一成人久久精品| 久久电影一区| 一二三区精品| 亚洲成色777777女色窝| 国产精品女主播一区二区三区| 久久婷婷国产麻豆91天堂| 在线视频日韩| 亚洲欧洲精品一区二区精品久久久| 亚洲欧美日韩高清| 亚洲黄色尤物视频| 国产日韩在线视频| 欧美性生交xxxxx久久久| 开心色5月久久精品| 性做久久久久久久久| 亚洲伦理中文字幕| 亚洲国产99| 毛片av中文字幕一区二区| 欧美专区亚洲专区| 亚洲综合成人在线| av成人手机在线| 91久久一区二区| 在线播放中文字幕一区| 国产欧美日韩一区二区三区在线| 欧美另类videos死尸| 久久综合久久综合久久| 久久久99免费视频| 欧美一区网站| 香蕉久久夜色| 欧美一区二区观看视频| 亚洲欧美国内爽妇网| 亚洲一卡二卡三卡四卡五卡| 日韩亚洲国产欧美| 99精品欧美一区| 一区二区三区久久精品| 日韩视频在线你懂得| 亚洲精品一区二区三区婷婷月| 亚洲激情成人网| 91久久精品美女高潮| 亚洲人成在线免费观看| 亚洲欧洲日本在线| 亚洲精品老司机| 在线中文字幕一区| 亚洲男女毛片无遮挡| 亚洲一区在线播放| 午夜亚洲一区| 久久夜色精品国产欧美乱极品| 久久久久久久久综合| 亚洲国产一区在线观看| 激情成人av在线| 黄色精品一区二区| 亚洲国产精品成人精品| 亚洲精品日本| 亚洲午夜精品久久| 欧美一区二区高清| 麻豆国产精品一区二区三区| 女人天堂亚洲aⅴ在线观看| 亚洲黄网站在线观看| 99re热这里只有精品视频| 亚洲小说欧美另类婷婷| 欧美在线免费观看| 欧美电影电视剧在线观看| 欧美日韩精品欧美日韩精品 | 欧美激情国产日韩| 国产精品国产| 在线播放日韩欧美| av成人老司机| 久久人人97超碰国产公开结果 | 欧美激情精品久久久久久变态| 亚洲国产片色| 亚洲在线电影| 免费日韩一区二区| 国产精品美女在线观看| 在线精品视频一区二区| 99在线|亚洲一区二区| 欧美中文字幕在线播放| 欧美电影在线观看完整版| 亚洲精品社区| 久久精品首页| 国产精品三级视频| 亚洲精品免费在线播放| 久久9热精品视频| 亚洲国内自拍| 久久gogo国模裸体人体| 欧美日本高清视频| 一区在线播放| 欧美一级艳片视频免费观看| 亚洲电影欧美电影有声小说| 午夜宅男久久久| 国产精品成人国产乱一区| 亚洲精华国产欧美| 久久精品亚洲国产奇米99| 日韩一级在线观看| 老牛国产精品一区的观看方式| 国产欧美91| 亚洲在线观看免费视频| 亚洲人成毛片在线播放女女|