1. 程式人生 > >藍橋杯 真題 測試次數(詳解)--------Five-菜鳥級

藍橋杯 真題 測試次數(詳解)--------Five-菜鳥級

                                                測試次數
x星球的居民脾氣不太好,但好在他們生氣的時候唯一的異常舉動是:摔手機。
各大廠商也就紛紛推出各種耐摔型手機。x星球的質監局規定了手機必須經過耐摔測試,並且評定出一個耐摔指數來,之後才允許上市流通。x星球有很多高聳入雲的高塔,剛好可以用來做耐摔測試。塔的每一層高度都是一樣的,與地球上稍有不同的是,他們的第一層不是地面,而是相當於我們的2樓。如果手機從第7層扔下去沒摔壞,但第8層摔壞了,則手機耐摔指數=7。
特別地,如果手機從第1層扔下去就壞了,則耐摔指數=0。
如果到了塔的最高層第n層扔沒摔壞,則耐摔指數=n為了減少測試次數,從每個廠家抽樣3部手機參加測試。某次測試的塔高為1000層,如果我們總是採用最佳策略,在最壞的運氣下最多需要測試多少次才能確定手機的耐摔指數呢?請填寫這個最多測試次數。注意:需要填寫的是一個整數,不要填寫任何多餘內容。

此題 答案為19  通過關係式 (K^3+5K)/6>=1000  (下為詳解)

解題思路:

  先說說題意 

    一共 1000 層   某款手機的耐摔指數 為 1~1000的任何值(超出1000 也按1000算),每款手機只有三部一模一樣的手機給我們測試用 也就是說 我們最多摔壞3次 而且 最後一次摔壞的層數就是該款手機的耐摔指數。你就需要制定一個最優的方案 適用與所有不同的手機測試並且測試次數要小於等於最壞情況下的次數。(最壞情況 就是 一個邊界測試次數,無論手機的耐摔指數是多少,總能在這個邊界測試次數前 找到該手機的耐摔指數)

   此題 二分肯定莫法搞 只有 3部手機 ,如果 手機耐摔指數為10 你二分 先來500層 一扔 碎了 再來250層 又碎了 就剩一部手機了 咋辦  你難道要扔 125 ,此時 你莫法 只有從老老實實從第一層 開始扔 才能扔到第10層測出結果,這樣你就會扔 1+1+10 =12 次 ,需要測試12次 才能得到 該手機的耐摔指數,可是如果 該手機的耐摔指數為 249 哪 按照二分 就得  1+1+249=251次。所以必須另闢思路

如果 只有一部手機給你測試 哪隻能 從第一層開始扔 最壞情況就是 從1扔到 1000層去,最壞情況就是1000次

如果 只有二部手機給你測試 ,這時候 就相當於多了一次機會 可以博上一博 減少點測試次數(準確的說是減少最壞情況下的測試次數),這個時候就需要假設一下了 ,最壞測試次數為 k 次  ,也就是說 無論你手機的耐摔指數為多少(1000內), 我都能通過k次測試 找到,那麼想想

假設 第 1 次隨便隨便選一層扔 ,選 第 i_1 層 碎了,那麼只好 從第1層 開始扔了 

最壞就是 耐摔指數為 i_1-1 要1+i_1-1=i_1 次測試 (同時保證  i_1<=k) 若沒碎就可以進行下一步

假設 第 2 次隨便隨便選一層扔 ,選第 i_2 層 碎了,那麼只好 從第 i_1 +1層 開始扔了

 最壞就是 耐摔指數為i_2 -1 要1+1+(i_2 -1)- i_1i_2 -i_1+1 次測試(同時保證  i_2 -i_1+1 <=k)若沒碎就可以進行下一步

假設 第 3次隨便隨便選一層扔 ,選第 i_3 層 碎了,那麼只好 從第i_2 +1層 開始扔了

 最壞就是 耐摔指數為 i_3 -1 要1+1+(i_3-1)-i_2 =i_3-i_2 +2 次測試  (同時保證  i_3-i_2 +2 <=k)若沒碎就可以進行下一步

。 

假設 第 k次隨便隨便選一層扔 ,選第 i_k 層 碎了,那麼只好 從第i_{k-1}+1層 開始扔了

 最壞就是 耐摔指數為 i_k-1 要1+1+1...1+(i_k-1)-i_{k-1}=i_k-i_{k-1}+(k-1) 次測試 (同時保證 i_k-i_{k-1}+(k-1) <=k, ) 

        然後 我們把它們 給排一排 如下 

                                                      i_1<=k

                                                    i_2 -i_1+1 <=k

                                                    i_3-i_2 +2 <=k

                                                        ......

                                             i_k-i_{k-1}+(k-1) <=k

      看到這樣的 忍不住 就 想消消元 於是乎 如下

            i_1+i_2 -i_1+1+i_3-i_2 +2...... i_k-i_{k-1}+(k-1)<=k*k

                  消掉元之後: 1+2+3....+(k-1)+i_k<=k*k 

                  前面常數求和公式     k*(k-1)/2 +i_k<=k*k 

            再變一下   i_k<=k*k-k(k-1)/2  即得到  i_k<=k*(k+1)/2 

                  再一想   i_k 是第k次 扔手機 所以 這是最後一次,要保證1~1000層所有情況都考慮即i_k>=1000

                  要想測試次數k 最少 所以 i_k當然取1000 於是乎 就得到

                  當給你兩部手時  在最壞情況下最小測試次數滿足  k*(k+1)/2>=1000 那麼k 就得出了

 現在 給的是 三部 手機,則用同樣的方法 設 最壞測試次數為 K 次  ,

 假設 第 1 次隨便隨便選一層扔 ,選 第 i_1 層 碎了,碎了我也有2部手機不是,

那麼 我此時想用兩部手機測出 1~(i_1 -1)範圍的耐摔指數就和上面情況一樣的

最壞測試次數滿足關係   k*(k+1)/2>=i_1-1= i_1-1  (同時保證  k+1<=K,===>k<=K-1注 :這是大 K  )  

 若沒碎就可以進行下一步

假設 第 2 次隨便隨便選一層扔 ,選第 i_2 層 碎了,碎了我也有2部手機不是,

那麼 我此時想用兩部手機測出 (i_1 +1)~( i_2-1)範圍的耐摔指數就和上面情況一樣的

最壞測試次數滿足關係 k*(k+1)/2>=( i_2​​​​​​​-1)-i_1 =i_2​​​​​​​- i_1-1 (同時保證  k+1+1 <=K,===>k<=K-2注 :這是大 K)

若沒碎就可以進行下一步

假設 第 3 次隨便隨便選一層扔 ,選第 i_3層 碎了,碎了我也有2部手機不是,

那麼 我此時想用兩部手機測出( i_2+1)~( i_3-1)範圍的耐摔指數就和上面情況一樣的

最壞測試次數滿足關係 k*(k+1)/2>=( i_3-1)-i_2​​​​​​​ =i_3​​​​​​​- i_2​​​​​​​-1 (同時保證  k+1+1+1 <=K,===>k<=K-3注 :這是大 K)

假設 第 k次隨便隨便選一層扔 ,選第 i_k 層 碎了,那麼只好 碎了我也有2部手機不是,

那麼 我此時想用兩部手機測出(i_{k-1}​​​​​​​+1)~( i_k-1)範圍的耐摔指數就和上面情況一樣的

最壞測試次數滿足關係 k*(k+1)/2>=( i_k-1)-( i_{k-1}​​​​​​​+1)=i_k​​​​​​​- i_{k-1}​​​​​​​ -1(同時保證  k+1+1....+1 <=K,===>k<=K-K注 :這是大 K)

  如法炮製 但是這裡的小k 每行是不一樣的所以要將他們 用大K 替換掉 

                                      k*(k+1)/2>=i_1-1= i_1-1                    k<=K-1

                                      k*(k+1)/2>=( i_2​​​​​​​-1)-i_1 =i_2​​​​​​​- i_1-1      k<=K-2

                                      k*(k+1)/2>=( i_3-1)- i_2​​​​​​​ =i_3​​​​​​​- i_2​​​​​​​-1       k<=K-3

                                                            ......

                                      k*(k+1)/2>=( i_k-1)- i_{k-1}​​​​​​​=i_k​​​​​​​- i_{k-1}​​​​​​​ -1    k<=K-K 

             替換後:

                                       (K-1)*K/2>=i_1-1= i_1-1

                                        (K-2)*(K-1)/2>=( i_2​​​​​​​-1)-i_1 =i_2​​​​​​​- i_1-1

                                        (K-3)*(K-2)/2>=( i_3-1)- i_2​​​​​​​=i_3​​​​​​​- i_2​​​​​​​-1

                                                                   ......

                                  (K-K)*(K-(K-1))/2>=( i_k-1)- i_{k-1}​​​​​​​=i_k​​​​​​​- i_{k-1}​​​​​​​ -1

 消消元:      1/2* [(K-1)*K+ (K-2)*(K-1)+(K-3)*(K-2)......(K-K)*(K-(K-1))]>=i_k-K

配湊法:   1/2* [k^2+(K-1)^2+ (K-2)^2+(K-3)^2......(K-(k-1))^2]-[K+(K-1)+(K-2)+(k-3)......+(K-(K-1))]>=i_k-K

              (同時增加減少 [K+(K-1)+(K-2)......(K-(K-1))]- [K+(K-1)+(K-2)......(K-(K-1))+(K-K)]  )

兩邊化簡一下:1/2* [K^2+(K-1)^2+ (K-2)^2+(K-3)^2......1^2]-[K+(K-1)+(K-2)+(k-3)......+(K-(K-1))+(K-K)]>=i_k-K

               ===>1/2* [K^2+(K-1)^2+ (K-2)^2+(K-3)^2......1^2]-[K*(K+1)-1-2-3.....-K]>=i_k-K

根據平方求和公式  :

                      所以  原式等於 1/2*{   K*(K+1)(2K+1)/6 -[K*(K+1)-K*(K+1)/2]>=i_k-K

                      ====>1/2*{   K*(K+1)(2K+1)/6 -[K*(K+1)-K*(K+1)/2]>=i_k-K

                      ====> (K^3+5K)/6 >= i_k==1000

                      ====>  K=19

        於是就得到了 公式

  如此類推 可以得到其4部手機 5部 手機等

程式碼 就隨便寫了

#include<stdio.h>
int main(){
    int i;
      for(i=0;i<100;i++)
	   if((i*i*i+i*5)/6>=1000)break;
	   printf("%d\n",i);
	return 0;
}