
給你一疊薄煎餅,請你寫一個程式來指出要如何安排才能使這些薄煎餅由上到下依薄煎餅的半徑由小到大排好。所有的薄煎餅半徑均不相同。
要把薄煎餅排好序需要對這些薄煎餅做翻面(flip)的動作。方法是以一抹刀插入一疊薄煎餅中,然後做翻面的動作(也就是說在抹刀上面的薄煎餅經翻面後,會依相反的次序排列)。若一疊共有n個薄煎餅,我們定義最底下的薄煎餅的位置為1,最上面的薄煎餅位置為n。當抹刀插入位置為k時,代表從位置k到位置n的薄煎餅要做翻面的動作。
要把薄煎餅排好序需要對這些薄煎餅做翻面(flip)的動作。方法是以一抹刀插入一疊薄煎餅中,然後做翻面的動作(也就是說在抹刀上面的薄煎餅經翻面後,會依相反的次序排列)。若一疊共有\(n\)個薄煎餅,我們定義最底下的薄煎餅的位置為1,最上面的薄煎餅位置為\(n\)。當抹刀插入位置為\(k\)時,代表從位置\(k\)到位置\(n\)的薄煎餅要做翻面的動作。
一開始時,這疊薄煎餅随意堆放,并以半徑大小來表示。例如:以下3疊薄煎餅(最左邊那一疊8是最上面一個薄煎餅的半徑)
對最左邊那疊薄煎餅,如果我們把抹刀插在位置3(就是半徑為7的那塊薄煎餅的下面)的地方做翻面,就會得到中間那疊,如果我們再把抹刀插在位置1(就是半徑為2的那塊薄煎餅的下面)的地方做翻面,就會得到最右邊那疊。
Input
每組測試資料一行,内容為這一疊薄煎餅一開始的狀态。每列開始的整數(介于1到100之間)代表位于最上方薄煎餅的半徑,依此類推。薄煎餅的數目介于1到30之間。請參考輸入樣例。
Output
對每一組測試資料輸出2列。第一列為原來那疊薄煎餅。第2列則為要使這疊薄煎餅由小到大排列所做的翻面的動作。數字代表抹刀所插入的位置。(0代表已完成)。如果已經排好了,則不需再有翻面的動作。請參考輸出樣例。
如果我們設題目輸入數組為\(A\),長度為\(n\)。那麼我們需要注意的一點是,\(A[0]\)對應一疊煎餅的頂端,\(A[n-1]\)對應一疊煎餅的底部。如下圖所示:
故要想将數組倒數第\(i\)個位置及其之前的元素(即\(A[0:n-i]\))翻轉,我們輸出的抹刀插入位置為\(i\)。
采用選擇排序的思想,按從大到小的順序依次把元素移動到正确位置,一共\(n\)輪,其中第\(i\)輪(\(i=1,2,...,n\))排序把數組\(A[0:n-i]\)中最大的元素移動到下标\(n-i\)處(如果本身就在下标\(n-i\)處則跳過)。
不過這裡我們隻能翻轉一個序列,故我們需要用到一個技巧,就是分兩步走:
① 先将\(A[0:n-i]\)中最大的元素“翻”到最左端的下标\(0\)處(如果本身就在下标\(0\)處則跳過)。
② 然後再将它“翻”到正确位置即下标\(n-i\)處。
設數組\(A[0:n-i]\)中數組最大元素的下标為\(maxs\),前者需要将\(A[0:maxs]\)(即倒數第\(n - maxs\)個位置及其之前的元素)翻轉,此時輸出的抹刀插入位置應為\(n-maxs\);後者需要将\(A[0:n-i]\)(即倒數第\(i\)個位置及其之前的元素翻轉,此時輸出的抹刀插入位置應為\(i\)。
根據以上的分析,我們的算法如下:
數學是符号的藝術,音樂是上界的語言。