藍橋杯 K倍區間

2021-10-03 19:22:40 字數 1675 閱讀 5219

時間限制:2.0s 記憶體限制:256.0mb

給定乙個長度為n的數列,a1, a2, … an,如果其中一段連續的子串行ai, ai+1, … aj(i <= j)之和是k的倍數,我們就稱這個區間[i, j]是k倍區間。

你能求出數列中總共有多少個k倍區間嗎?

輸入格式

第一行包含兩個整數n和k。(1 <= n, k <= 100000)

以下n行每行包含乙個整數ai。(1 <= ai <= 100000)

輸出格式

輸出乙個整數,代表k倍區間的數目。

521

2345

6
資料規模和約定

峰值記憶體消耗(含虛擬機器) < 256m

cpu消耗 < 2000ms

請嚴格按要求輸出,不要畫蛇添足地列印類似:「請您輸入…」 的多餘內容。

注意:main函式需要返回0;

只使用ansi c/ansi c++ 標準;

不要呼叫依賴於編譯環境或作業系統的特殊函式。

所有依賴的函式必須明確地在原始檔中 #include

不能通過工程設定而省略常用標頭檔案。

提交程式時,注意選擇所期望的語言型別和編譯器型別。

解題思路:本題通過暴力搜尋複雜度為o(n2)顯然對於大規模資料是會超時的,所以用字首和進行處理(用sum陣列記錄字首和),所以區間l-m的和為k的倍數可以表示為(sum[m]-sum[l - 1]) % k == 0我們進行移項之後可以得到sum[m] % k == sum[l - 1] % k。所以對任意有相同餘數的區間進行選取,最後要注意餘數為0表示從起始位置到該位置的和剛好為k的倍數,所以最後要加上。

**:

#include

#define ll long long

intmain

(void);

int hash[

100010]=

;scanf

("%d %d"

,&n,

&k);

for(

int i =

1;i <= n;i++

)printf

("%lld"

,ans + hash[0]

);return0;

}

一開始對於上面sum[i] = (sum[i - 1] +temp) % k;這一步在求字首和的過程中直接取餘數不太理解,其實效果是一樣的也可以像下面這樣先求出字首和再取餘。但是要注意sum陣列資料型別要換成long long否則會溢位。上面**修改的地方注釋掉了

**:

#include

#define ll long long

intmain

(void);

ll sum[

100010]=

;int hash[

100010]=

;scanf

("%d %d"

,&n,

&k);

for(

int i =

1;i <= n;i++

)printf

("%lld"

,ans + hash[0]

);return0;

}

藍橋杯 k倍區間

題目描述 給定乙個長度為n的數列,a1,a2,an,如果其中一段連續的子串行ai,ai 1,aj i j 之和是k的倍數,我們就稱這個區間 i,j 是k倍區間。你能求出數列中總共有多少個k倍區間嗎?輸入 第一行包含兩個整數n和k.1 n,k 100000 以下n行每行包含乙個整數ai。1 ai 10...

藍橋杯 k倍區間

暴力模擬 雙迴圈肯定超時了,需要找到數字間的規律進行優化 includeusing namespace std typedef long long ll define maxn 100005 sum r sum l 1 就是區間 l,r 的和。區間 l,r 的和是k的倍數即 sum r sum l ...

藍橋杯 K倍區間

給定乙個長度為 n nn 的數列,a1,a2,an a 1,a 2,a n a1 a2 a n 如果其中一段連續的子串行 ai,ai 1 aj a i,a a j ai ai 1 aj 之和是 k kk 的倍數,我們就稱這個區間 i,j i,j i,j 是 k kk倍區間。你能求出數列中總共有多少個...