PAT菜雞進化史 乙級 1035

2021-09-11 20:45:33 字數 1985 閱讀 7267

根據維基百科的定義:

插入排序是迭代演算法,逐一獲得輸入資料,逐步產生有序的輸出序列。每步迭代中,演算法從輸入序列中取出一元素,將之插入有序序列中正確的位置。如此迭代直到全部元素有序。

歸併排序進行如下迭代操作:首先將原始序列看成 n 個只包含 1 個元素的有序子串行,然後每次迭代歸併兩個相鄰的有序子串行,直到最後只剩下 1 個有序的序列。

現給定原始序列和由某排序演算法產生的中間序列,請你判斷該演算法究竟是哪種排序演算法?

輸入在第一行給出正整數 n (≤100);隨後一行給出原始序列的 n 個整數;最後一行給出由某排序演算法產生的中間序列。這裡假設排序的目標序列是公升序。數字間以空格分隔。

首先在第 1 行中輸出insertion sort表示插入排序、或merge sort表示歸併排序;然後在第 2 行中輸出用該排序演算法再迭代一輪的結果序列。題目保證每組測試的結果是唯一的。數字間以空格分隔,且行首尾不得有多餘空格。

1031

2875

9460

1237

8594

60

insertion sort12

3578

9460

1031

2875

9406

1328

5749

06

merge sort12

3845

7906

這題印象也是深刻的啊,bug改了蠻久的!

首先判斷是插入還是歸併很簡單,把給出的排過序的序列和自己sort的序列對比一下,找到未排序的部分,如果未排序的部分與原序列完全相同,則是插入,否則是歸併

我這裡是用了兩個指標,分別指向第乙個未排序元素與第乙個不相同元素,若不相同元素超出陣列了,說明是插入排序(即序列的未排序部分沒變過)

然後是多排序一次的部分,這部分對選擇排序很簡單,用sort一下子就解決了,問題主要出在歸併排序身上

歸併排序需要先找到我們上一次排序的「歸併節」長度,我是先找了小於index_1的最大冪,然後判斷它是不是上一次的「歸併節」,不是就減半,到2為止(不用也不能考慮到1為止,因為1的話其實就變成了插入排序,並且會導致後續迴圈出現問題)

找到「歸併節」後就很簡單了,歸併節翻倍然後開始一節一節排序

在此尤其需要注意下標!!切記切記!!

#include

#include

#include

intmain()

else}if

(flag ==0)

break;}

for(

int i = n / len * len; i < n -

1; i++)}

if(flag ==1)

break

;else

len /=2

;}for(

int i =

0; i < n /

(len *2)

; i++

)sort

(sorted.

begin()

+ i *

2* len, sorted.

begin()

+ i *

2* len +

2* len)

;sort

(sorted.

begin()

+ n /

(len *2)

* len *

2, sorted.

begin()

+ n);}

for(

int i =

0; i < n -

1; i++

) cout << sorted[i]

<<

" ";

cout << sorted[n -1]

;return0;

}

PAT菜雞進化史 乙級 1001

卡拉茲 callatz 猜想 對任何乙個正整數 n,如果它是偶數,那麼把它砍掉一半 如果它是奇數,那麼把 3n 1 砍掉一半。這樣一直反覆砍下去,最後一定在某一步得到 n 1。卡拉茲在 1950 年的世界數學家大會上公布了這個猜想,傳說當時耶魯大學師生齊動員,拼命想證明這個貌似很傻很天真的命題,結果...

PAT菜雞進化史 乙級 1005

卡拉茲 callatz 猜想已經在1001中給出了描述。在這個題目裡,情況稍微有些複雜。當我們驗證卡拉茲猜想的時候,為了避免重複計算,可以記錄下遞推過程中遇到的每乙個數。例如對 n 3 進行驗證的時候,我們需要計算 3 5 8 4 2 1,則當我們對 n 5 8 4 2 進行驗證的時候,就可以直接判...

PAT菜雞進化史 乙級 1013

令 p ip i pi 表示第 i 個素數。現任給兩個正整數 m n 10 4 請輸出p mp m pm 到 p np n pn 的所有素數。輸入在一行中給出 m 和 n,其間以空格分隔。輸出從 p mp m pm 到 p np n pn 的所有素數,每 10 個數字佔 1 行,其間以空格分隔,但行...