罐子和硬幣-c#求解-英雄會在線編程題目

       各位朋友新年好!過完年後來csdn逛逛,發現上了新的編程題目,一道罐子和硬幣,一道搜索排序。今天就先說罐子和硬幣的題目。先看題目:

罐子和硬幣
  • 發佈公司:
  • 有 效 期:
  • 賽    區:
  • CSDN                
  • 2014-01-242014-03-02
  • 北京
  • 難 度 等 級:
  • 答 題 時 長:
  • 編程語言要求:
  • 120分鐘
  • C C++ Java C#                 
題目詳情

有n個罐子,有k個硬幣,每個罐子可以容納任意數量的硬幣。罐子是不透明的,起初你可以隨機把這k個硬幣任意放在罐子裏。然後罐子被打亂順序,你從外表無法區別罐子。最後罐子被編上號1-n。你有p次機會,每次你可以選擇某個罐子,如果該罐子裏有硬幣,則你可以得到1個(你不可以知道該罐子裏有多少硬幣),如果該罐子是空的,你得不到任何硬幣。你最終要得到至少c枚硬幣,我們的問題是給定n,k,c,求出最少的p,存在一種你最初放硬幣的方式,無論罐子如何被打亂順序,你都能p次機會內獲得至少c個硬幣。

輸入n,k,c (0 < n <=1000000, 0 < c <= k <=1000000)。

輸出,最小的p值。

例如n = 3, k = 6, c = 4。 你可以把每個罐子放入兩個硬幣,這樣得到4次機會可以得到4個硬幣,輸出4。

 

       題目看起來挺簡單的,仔細想想似乎又不簡單。

分析:這道題其實對編程考察的不多,主要是考察思維方式。即你如何放硬幣,如何取硬幣的方式。

我最開始是這麼想的,把硬幣平均放在每個瓶子裏面,取硬幣的時候,每個瓶子輪流取。直到取到c個,問題是,平均放,可能有些瓶子裝的少一個,即k%n !=0,比如說n=10,k=28,那麼每個瓶子裝2個,還有8個瓶子多裝一個,裝了3個,如果我們要取25個,即c=25,前20個比較好取,後5個怎麼取?按照這種裝法,至少還要取2+5=7次,因爲有2次你可能摸到的是空瓶子。但是這種取法是不是最優了?如果k=21,c=21了?那不是要取20+1+9=30次。顯然,我們可以吧最後一個瓶子裏面的兩個金幣放到前面不是3個金幣的瓶子裏面,這樣取得次數就少於30,再依次移動最後一個瓶子裏面的金幣到前面不是3個金幣的瓶子,使其金幣數達到3個,我們發現,次數都會逐漸減少,直到不能移動爲止。

 

現在回過頭來看下,這道題基本上思路就比較清晰了。

步驟

1、首先將硬幣平均分配到每個瓶子,如果k%n==0,那麼取c個硬幣只需要c次。

2、如果k%n  !=0  ,那麼我們就要考慮要取多少個硬幣,如果c<Math.Floor(k/n)*n,很顯然平均分配硬幣,然後輪流取每個瓶子,c次就可以取到了。

3、當k%n  !=0 時,而c>=Math.Floor(k/n)*n的時候,也就是我們上面分析的,這個時候就要從最後一個瓶子開始抽取硬幣,補充到前面沒有裝滿的瓶子。

這個如果用畫圖的方式展現,就很好理解了:

瓶1,瓶2,............瓶n

1,1,1,1,。。。,1

1,1,1,。。。。。1

。。。。。。。。

1,1,。。,0,0.。0

首先平均分配,發現後面還有n-k%n個瓶子少一個硬幣,因此,吧最後一個瓶子裏面的硬幣拿出來補充這(n-k%n +1)個瓶子裏,不足,就再下一個瓶子裏的硬幣,最後形成了這樣一個圖:

瓶1,瓶2,............瓶n

1,1,1,1,。。。1...0

1,1,1,。。。。1...0

。。。。。。。1...0

1,1,。。,   1,0...0

其中行數row = k / n + 1;

而這n個瓶子中有col=k/row 個瓶裝的一樣多,剩下的瓶子,要麼全爲空,或者有一個吧剩下的硬幣裝進去了,很顯然,這時候要取c個硬幣,最差的情況p= n - col + c;

ok,到此分析完畢了,也就是三種情況,代碼也非常的少,大概十多行吧,提交,沒問題,通過。

 

 

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