騰訊編程馬拉松初賽第五場 – 第一題(威威貓系列故事——吃雞腿)

來源:互聯網
上載者:User

Problem Description  威威貓不是一隻普通的貓,普通的貓喜歡吃魚,但威威貓最喜歡吃雞腿。他每天都在不停的吃啊吃,吃了一隻又一隻雞腿。現在他遇到了一個難題,如果他的體重太胖那麼他的主人就不給他吃雞腿了,所以他需要你的協助。
  威威貓的身體由n個器官構成,由於他的身體很特殊所以他的增長也很特殊(不要問為什麼,喜歡吃雞腿的貓已經夠奇怪了)。他的增長有個k1和k2係數,而且每天的增長量和前一天有關,我們假設這n個器官在第i天的數值分別是a(i,1), a(i,2), a(i,3) …… a(i,n),那麼,第i+1天他每個器官的數值就會變成:
  a(i+1,1) = k1 * a(i,1) + k2 * a(i,2)
  a(i+1,2) = k1 * a(i,2) + k2 * a(i,3)
  ......
  a(i+1,n) = k1 * a(i,n) + k2 * a(i,1)
  威威貓的體重等於他的所有器官的數值之和,並且他還擁有一個特殊的機能,就是會自動檢測自己的體重,如果他的體重比K大,那麼就會自動停止生長(為了每天都能吃到雞腿),由於威威貓的特殊身體構造他的體重是可能會變成負數的。
  現在我給你n個器官的初始數值和他的增長係數k1,k2,請問他幾天之後會停止生長,如果他永遠無法停止生長那麼就輸出"inf"。(引號不用輸出) 


Input輸入資料第一行是一個正整數T,表示有T組測試資料;
每組資料的第一行包含4個數字n,k1,k2,k,代表威威貓有n個器官,他的生長係數是k1,k2,當體重超過k的時候他就停止生長。
接下來的一行是n個數ai,代表威威貓每個器官第一天的數值是多少。

[Technical Specification]
T <= 100
1 <= n <= 10000
-100 <= k1, k2 <= 100
1 <= k <= 10 ^ 18
1 <= ai <= 1000(1 <= i <= n)  


Output對於每組測試資料,請首先輸出"Case #X: ",X代表測試案例的編號,然後輸出一個數ans,代表ans天之後他會停止生長,如果不會停止就輸出inf.
具體可參見sample output。 


Sample Input

25 1 1 101 1 1 1 15 1 1 5001 1 1 1 1
 


Sample Output

Case #1: 2Case #2: 7

AC代碼:

#include <stdio.h>#include <string.h>#include <stdlib.h>int main(){int testcase,i,n,count,ans;double k,sum,k1,k2,temp;scanf("%d",&testcase);for(count=1; count<=testcase; count++){ans = 0;sum = 0;scanf("%d %lf %lf %lf",&n,&k1,&k2,&k);for(i=0;i<n;i++){scanf("%lf",&temp);sum = sum + temp;}if(sum > k)printf("Case #%d: 0\n",count);else if(k1+k2>1 || k1+k2<-1){while(sum<=k){sum = sum * ( k1 + k2 );ans++;}printf("Case #%d: %d\n",count,ans);}else{printf("Case #%d: inf\n",count);}}return 0;}


題目分析:此題難度不大,但是AC率極低,因為題中存在一個很隱形陷阱。

由題目描述,我們可以抽象出公式sum(i+1) = (k1+k2)*sum(i),目標是當sum大於k時,則停止生長;若sum永遠不可能大於k,則無法停止生長,直接輸出inf即可。

由於-100 <= k1, k2 <= 100,所以k1+k2可正可負也可為0。當k1+k2等於0,-1或1時,顯然永遠無法停止生長,輸出inf。其餘情況,則需要根據sum(i+1) = (k1+k2)sum(i)計算即可,數一下迭代的次數,即可算得多少天之後可停止生長。

現在來說一下此題的陷阱:64位整型在運算時會溢出。k的取值範圍是1 <= k <= 10 ^ 18,這個數超過了32位整型變數,但是用64位整型可表示。帶符號的64位整型最大值為2^63 - 1,這個數大於10
^ 18,乍一看,好像不會有什麼問題。但是公式sum(i+1) = (k1+k2)*sum(i)在迭代的時候,會超過2^63 - 1,也就說會溢出發生錯誤。原因是sum(i)理論上最大可與k相等,k1+k2的最大值為200,相乘得200*10
^ 18大於2^63 - 1,這證明了極端情況會發生溢出。所以說用64位整型變數會出現錯誤,應該用double表示才可,儘管輸入都是整數。我當時做此題時,一直不明白錯在哪裡,比賽結束之後才發現問題所在。

如果非要使用64位整型變數也可,需要程式做一下改動,在相乘的時候不要發生溢出,也可AC,代碼如下:

#include <stdio.h>#include <string.h>#include <stdlib.h>int main(){int testcase,i,n,count,ans;__int64 k,sum,k1,k2,temp;scanf("%d",&testcase);for(count=1; count<=testcase; count++){ans = 1;sum = 0;scanf("%d %I64d %I64d %I64d",&n,&k1,&k2,&k);for(i=0;i<n;i++){scanf("%I64d",&temp);sum = sum + temp;}if(sum > k)printf("Case #%d: 0\n",count);else if(k1+k2>1 || k1+k2<-1){while(1.0*(k1+k2)*sum<=1.0*k){sum = sum * ( k1 + k2 );ans++;}printf("Case #%d: %d\n",count,ans);}else{printf("Case #%d: inf\n",count);}}return 0;}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.