PTA平臺 自測-3 數組元素循環右移問題

中國大學MOOC-陳越、何欽銘-數據結構-起步能力自測題

自測-3 數組元素循環右移問題   (20分)

一個數組A中存有N(>0)個整數,在不允許使用另外數組的前提下,將每個整數循環向右移M(M≥0)個位置,即將A中的數據由(A0 A1.. A{N-1})變換爲(A{N-M} ... A{N-1} A0 A1 ... A{N-M-1} )(最後M個數循環移至最前面的M個位置)。如果需要考慮程序移動數據的次數儘量少,要如何設計移動的方法?

輸入格式:

每個輸入包含一個測試用例,第1行輸入N(1≤N≤100)和M(M≥0);第2行輸入N個整數,之間用空格分隔。

輸出格式:

在一行中輸出循環右移MM位以後的整數序列,之間用空格分隔,序列結尾不能有多餘空格。

問題分析:

要實現移動次數儘量少,所以我們可以思考一下最少需要移動幾次。最少應該是N次(M不爲0時)。如果我們假設N個整數中存在一個沒有移動,那麼這個元素之前的第M個元素需要移動到這個位置,那麼這個元素如果沒有移動,它的值將被覆蓋,換句話說這個數組將永遠失去一個元素,顯然這種情況是不被允許的。所以每個元素都需要至少移動一次。

Case 1 我們首先觀察一個例子,數組(1, 2, 3, 4, 5, 6, 7)向右移動2個位置,那麼1需要到3,3需要到5,5需要到7,7需要到2,2需要到4,4需要到6,6需要到1,如此移動7次,我們實現了循環移動的過程,而且僅僅移動了7次。是不是所有的數組都可以通過這樣的方式實現移動呢?答案是不一定。

Case 2 我們再來觀察一個例子數組(1, 2, 3, 4, 5, 6)向右移動2個位置,那麼1需要到3,3需要到5,5需要到1。那麼接下來呢?我們如果不選擇作出一些改變的話,我們將進入這個1,3,5的循環裏,而這顯然不是我們需要的,所以再回到1之後,我們需要調整到2,然後開始新的循環移動,這樣就可以完成2,4,6的位置改變。

這時候需要思考,究竟什麼情況下Case 1會發生,而什麼時候case 2會發生呢?

假設我們最最開始移動的元素下標爲a0,數組長度爲L,移動距離爲M (討論中M<L, 因爲M=L時數組發生沒有任何改變,而M>L總可以劃歸到M<L的情況裏) ,已經發生了第k次移動,那麼很容易得到第k次移動時,需要被移動的元素的下標爲:

ak = (a0 + M* k) % L. 而如果ak等於a0,那麼case 2就會發生,如果ak始終不等於a0,那麼我們一直處於case 1中。

更具體一點:

case 1:(M* k) % L != 0

case 2 :(M* k) % L  == 0

在完成了以上分析後,我們得到代碼實現如下:(python 3, 已通過PTA平臺全部測試案例)

 

 


 
  1. # This code is designed to adjust given array/list
  2. # by shifting every element by M units rightwards
  3. # circularly
  4. # e.g. a= [1, 2, 3, 4, 5, 6] M=2 -->
  5. # this input set will give out [5, 6, 1, 2, 3, 4]
  6. # sample input :
  7. # 6 2 (length of array, shift distance)
  8. # 1 2 3 4 5 6 (elements of array)
  9. ############## input processing #################
  10. InputInfo_1 = input("")
  11. InputInfo_2 = input("")
  12. InputList_1 = InputInfo_1.split(' ', 1)
  13. array_len = int( InputList_1[0] ) #get the length of array
  14. shift_dist = int ( InputList_1[1] ) #shift distance rightwards
  15. InputList_2 = InputInfo_2.split(' ', array_len-1 )
  16.  
  17. originalArray = [0] * array_len #initiate a list with all 0s
  18. for k in range(array_len) :
  19. originalArray[k] = int( InputList_2[k] ) # Transfer string var to int var
  20.  
  21. shift_dist = shift_dist % array_len
  22.  
  23. pre_repository = originalArray[0]
  24. this_index = ( 0 + shift_dist ) % array_len
  25. for m in range(array_len) :
  26. if (shift_dist * (m+1) ) % array_len != 0 :
  27. post_repository = originalArray[this_index]
  28. else:
  29. post_repository = originalArray[ (this_index +1 ) % array_len]
  30. originalArray[this_index] = pre_repository
  31. if (shift_dist * (m+1) ) % array_len != 0 :
  32. pre_repository = post_repository
  33. this_index = ( this_index + shift_dist ) % array_len
  34. else:
  35. pre_repository = originalArray[ (this_index +1 ) % array_len]
  36. this_index = ( this_index + shift_dist + 1 ) % array_len
  37.  
  38. for n in range(array_len - 1):
  39. print(originalArray[n], end =' ')
  40. print(originalArray[-1])
  41.  

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章