C++實現 藍橋杯 k倍區間
這裡是題目連結
k倍區間
題目大意
簡單來說,給你一個陣列和一個數k,讓你滿足陣列中連續區間和為k的倍數的區間有幾個
思路
看到題目的連續區間的時候,就知道這題使用字首和來寫的,然後我喜聞樂見的TLE了 ,咳咳,看了題目100000組資料,那n2資料妥妥的過不了了,只能是看看怎麼畫了,於是想到一個定理,(A+B)mod k = A mod k + B mod k。 (A-B)mod k= A mod k - B mod k這樣就有思路了
為了說明方便,我們設這個陣列有{1,2,3,4,5},k為2
首先,對於陣列num, 我們算出它的各個字首和的餘數,然後依此遍歷,設一個計數的陣列cnt[i]表示餘數為 i 的個數,這樣,遍歷過程中,有兩種情況
1.當前元素餘數為1,則此時,由上面的(A-B)mod k =A mod k -B mod k可知,增加的k倍區間個數為cnt[1]的值.簡單來說,cnt[1]為之前找到餘數為1的字首和的個數,如果cnt[1]>0,那麼前面至少有一個餘數為1的字首和,和一個餘數為1的當前的字首和序列,則這兩個序列之間的餘數差為0,則意味著兩個餘數為1的字首和,他們之間的區間就是k倍區間,所以當增加的k倍區間個數有cnt[1]個
2.當前元素餘數為0的情況差不多,增加的k倍區間個數為cnt[0]個
注意到了最後,我們還要格外給答案加上cnt[0]的值,因為餘數為0的字首和本身也是一個k倍區間呀!
那麼剩下的程式碼問題就很簡單了
#include <iostream>
using namespace std;
const int MAXN = 100000+5;
int num[MAXN],cnt[MAXN];
int main() {
int n,k;
cin>>n>>k;
for(int i=0; i<n; i++) {
cin>>num[i];
}
num[0]%=k;
for(int i=1;i<n;i++){
num[i]=(num[i]+num[i-1])%k;
}
// for(int i=0;i<n;i++){
// printf("num[%d]=%d\n",i,num[i])
// }
long long ans=0;
for(int i=0;i<n;i++){
ans+=(cnt[num[i]]);
cnt[num[i]]++;
// printf("cnt[%d]=%d ans=%d\n",num[i],cnt[num[i]],ans);
}
cout<<ans+cnt[0]<<endl;
return 0;
}
相關文章
- 藍橋杯-k倍區間
- 藍橋杯-連號區間數
- 藍橋杯 演算法訓練 區間k大數查詢 (Java解題)演算法Java
- 藍橋杯 排序排序
- 藍橋杯 航班時間 (字串處理)C字串
- 【每週例題】藍橋杯 C++ 多數C++
- 藍橋杯-N皇后
- 藍橋杯真題
- 【藍橋杯考前突擊】第十一屆藍橋杯校賽模擬C/C++ 正整數序列C++
- 2013藍橋杯題解c組C++C++
- 藍橋杯年號字串字串
- 藍橋杯-帶分數
- 藍橋杯-翻硬幣
- 藍橋杯-螞蟻感冒
- 藍橋杯 計算方程
- 藍橋杯-座次問題
- 藍橋杯-長草(BFS)
- 藍橋杯-日期問題
- 藍橋杯-班級活動
- 【藍橋杯考前突擊】第十屆藍橋杯省賽C/C++大學B組 試題 D 數的分解C++
- 歷屆藍橋杯省賽(C、C++)的答案(轉)C++
- Java實現 藍橋杯 演算法提高 八數碼(BFS)Java演算法
- 藍橋杯 演算法訓練 K好數(Java解題)演算法Java
- 藍橋杯——查詢的妙趣
- 密碼脫落——藍橋杯密碼
- 藍橋杯-串的處理
- 藍橋杯-回形巢狀巢狀
- 藍橋杯-分巧克力
- 藍橋杯學習路線
- 藍橋杯javaB組備賽Java
- 太陽(藍橋杯14屆)
- 藍橋杯-走迷宮(BFS)
- 藍橋杯-地宮取寶
- 藍橋杯-波動數列
- 藍橋杯-日誌統計
- 藍橋杯-合併數列
- 第九屆藍橋杯省賽C++A組 倍數問題(dfs)C++
- 第十三屆藍橋杯省賽C/C++ B組C++