將 的任意乙個排列進行排序並不困難,這裡加一點難度,要求你只能通過一系列的 swap(0, *) —— 即將乙個數字與 0 交換 —— 的操作,將初始序列增序排列。例如對於初始序列 ,我們可以通過下列操作完成排序:
swap(0, 1) ⟹
swap(0, 3) ⟹
swap(0, 4) ⟹
本題要求你找出將前 n 個非負整數的給定排列進行增序排序所需要的最少的與 0 交換的次數。
輸入格式:
輸入在第一行給出正整數 n (≤105 );隨後一行給出 的乙個排列。數字間以空格分隔。
輸出格式:
在一行中輸出將給定序列進行增序排序所需要的最少的與 0 交換的次數。
輸入樣例:
103 5 7 2 6 4 9 0 8 1
輸出樣例:
思路
這道題目抽象出來,是一道表排序的題,就是尋找「環」。
上圖中有3個環,但是a[2]是自環路,不需要做位置上的調整,所以在計算環的數量的時候,不考慮這種自環路。
首先要區別第乙個陣列元素是否為0,它對交換次數的計算公式有影響,可以用乙個flag變數標記。
用findnextindex函式來尋找,哪個陣列元素的下標和它的值不同,接著用順著這個值去尋找下乙個元素,直到環封閉。此時計算環的數量cn變數需要加1。
如果用findnextindex函式,每次都從頭開始檢查,那麼會大大增加程式的時間複雜度(我第一次就是這麼做的),最好的方法是記錄從環退出的位置,這個位置之前的元素一定是排好的,尋找下乙個環開頭,只需要在這個元素之後尋找就行。
交換次數計算公式:
對於以上的計算公式,可以自己列舉例子推算得到
實現
#include
void
inputnumber
(int
*p,int n)
}int
findnextindex
(int
*p,int begin,
int n)
return-1
;}intbasiccount
(int
*p,int n)
return count;
}int
main()
else
break;}
cn++
; nextindex =
findnextindex
(p, oldnextindex, n);}
if(cn==0)
ct =0;
if(flag ==0)
ct = basicn+
(cn-1)
*1-1
;else
ct = basicn+cn;
printf
("%d"
, ct)
;}
案例7 1 5 與零交換 25分
將 的任意乙個排列進行排序並不困難,這裡加一點難度,要求你只能通過一系列的 swap 0,即將乙個數字與 0 交換 的操作,將初始序列增序排列。例如對於初始序列 我們可以通過下列操作完成排序 輸入格式 輸入在第一行給出正整數 n 10 5 隨後一行給出 的乙個排列。數字間以空格分隔。輸出格式 在一行...
資料結構PTA 案例6 1 5 旅遊規劃
有了一張自駕旅遊路線圖,你會知道城市間的高速公路長度 以及該公路要收取的過路費。現在需要你寫乙個程式,幫助前來諮詢的遊客找一條出發地和目的地之間的最短路徑。如果有若干條路徑都是最短的,那麼需要輸出最便宜的一條路徑。輸入格式 輸入說明 輸入資料的第1行給出4個正整數n m s d,其中n 2 n 50...
pta資料結構
是否二叉搜尋樹 這題只要是了解二叉查詢樹的特點。bool isbst bintree t while right1 return isbst t left isbst t right 線性探測法的查詢函式 主要注意雜湊函式,這裡那個常量是真的坑,卡了半天。position find hashtabl...