藍橋杯 歷屆試題 數字遊戲(數列)

2021-09-26 14:31:53 字數 1699 閱讀 4707

問題描述

棟棟正在和同學們玩乙個數字遊戲。

遊戲的規則是這樣的:棟棟和同學們一共n個人圍坐在一圈。棟棟首先說出數字1。接下來,坐在棟棟左手邊的同學要說下乙個數字2。再下面的乙個同學要從上乙個同學說的數字往下數兩個數說出來,也就是說4。下乙個同學要往下數三個數,說7。依次類推。

為了使數字不至於太大,棟棟和同學們約定,當在心中數到 k-1 時,下乙個數字從0開始數。例如,當k=13時,棟棟和同學們報出的前幾個數依次為:

1, 2, 4, 7, 11, 3, 9, 3, 11, 7。

遊戲進行了一會兒,棟棟想知道,到目前為止,他所有說出的數字的總和是多少。

輸入格式

輸入的第一行包含三個整數 n,k,t,其中 n 和 k 的意義如上面所述,t 表示到目前為止棟棟一共說出的數字個數。

輸出格式

輸出一行,包含乙個整數,表示棟棟說出所有數的和。

樣例輸入:3 13 3 樣例輸出:17

樣例說明:棟棟說出的數依次為1, 7, 9,和為17。

資料規模和約定:1 < n,k,t < 1,000,000;

---分割線---

分析:我們看一下報數時會出現的數字(不做取餘處理,上面是報數,下面是差值):

1  	2  	4  	7  	11	 16	  22    29	  37	46	……			

1 2 3 4 5 6 7 8 9 ……

我們單獨看一下棟棟的報數: 1 7 22 46……

不難發現這些資料服從以下規律:

1 

1 + ( 1 + 2 + 3 ) = 7

1 + ( 1 + 2 + 3 ) + ( 4 +5 + 6 ) = 22

由此可以得到棟棟報數的乙個通項公式:num = 1 + n (n+1) / 2 (其中n表示棟棟報數時對應的序號-1,顯然n取值是:0,3,6,9,……)

知道了通項公式,以及總的迴圈次數,直接迴圈求和就是

但是,這樣的下場是:拿不到滿分

為什麼?

仔細看題,t和k的取值最大會接近100 0000,這時候如果僅僅只是利用上面的這個公式來求每次的報數num並求和然後再取餘,則num總會在某個值時發生溢位現象(num的數量級極限會取到100 0000^4,顯然溢位了long long),這時後面所有的num都將錯誤。所以這個方案是不可行的

為了避免這個溢位問題,我們應該想到利用前一次num的數值與下一次num的數值之間的差值來完成對num的變化,即利用這個差值來實現資料的更新(因為這之間的差值不會超過long long)

於是我們需要來推算一下(或者說來求出)這個差值量與序數n的關係,即求出這個函式。我們假設,有n個同學參與數字遊戲,那麼對於乙個週期(n)而言

棟棟兩次報數的差值是乙個關於n的函式:

△x=1+(n+n) [(n+n)+1] / 2 - [ 1+n(n+1) / 2 ] = n(n+2*n+1)/2

這樣就可以利用上面的公式,通過上一次num的值,用加法來把下一次的num計算出來,然後取餘,疊加到sum中(這樣顯然是不會產生資料溢位的現象的)

下面給出本題的完整**:

---分割線---

#include

using

namespace std;

intmain()

cout

}

藍橋杯 歷屆試題 數字遊戲

這道題給了乙個很明顯的乙個序列,那麼就是數列可以一次寫為 1 0 1 0 1 1 0 1 2 1 0 1 2 3 1 0 1 2 n 1 這樣就轉化為1加上乙個等差數列,那麼直接按照等差數列求和公式sn a1 an n 2 這樣就很容易求出答案。但是中間用公式的時候會用到i n i n 1 注意i和...

藍橋杯 歷屆試題 數字遊戲

先看到資料規模,如果純暴力的話10 6 10 6肯定是要超時的,所以我們要想辦法優化,因為我們只關心棟棟報出的數字總和,我們又知道了其他人報的規律是前面乙個人的 1 2 3 4這樣報的,那麼換句話來說,我們只要知道每迴圈一組總共加了多少,把這些總和加起來加到棟棟上次報的數字上,就能知道棟棟這次報的數...

藍橋杯 歷屆試題 數字遊戲

時間限制 1sec 記憶體限制 128mb 提交 612 解決 78 題目描述 棟棟正在和同學們玩乙個數字遊戲。遊戲的規則是這樣的 棟棟和同學們一共n個人圍坐在一圈。棟棟首先說出數字1。接下來,坐在棟棟左手邊的同學要說下乙個數字2。再下面的乙個同學要從上乙個同學說的數字往下數兩個數說出來,也就是說4...