1. 程式人生 > 實用技巧 >2020級cpp機考模擬題A卷-#題解2

2020級cpp機考模擬題A卷-#題解2

這部分的題目都有一定難度,有興趣的同學可以鑽研一下。

特此感謝來自BDT20030 tql的支援。


2:素數的和-2

題意:

計算不大於m的素數之和。(多麼容易理解的題目啊,對吧)

題解(有點複雜的演算法實現):

這題的難度就在於如何在不超時的情況下完成計算。(ps:記憶體上沒卡你,不然更痛苦)

請直接看程式碼,註釋打了真的很久,把30號的超綱程式碼改得不超綱還能綠也用了好久。

上板子:

#include<iostream>
#include<cmath>
using namespace std;
const int M = 10000005, mod = 100000007;//因為m的最大值是10000000,定義一個常量稍大於m就可以了
bool b[M];//都定義為全域性變數,可以在主函式裡呼叫 int p[M], cnt = 0;//p用於儲存m以內的全部素數,cnt為個數 void k() { for (int i = 2;i <= M;i++)//1不是素數,所以b[1]=0. { b[i] = 1;//先當他們全是素數,下面再用迴圈判斷 } for (int i = 2;i <= M;i++)//判斷M以內的各個數字是否為素數 { if (b[i])//b[ ]用於判斷各個數字是否為素數,是則=1,不是=0 { cnt++;//
用於記錄p中有幾個資料 p[cnt] = i;//p[ ]用於儲存各個<=M的素數 } for (int j = 1;j <= cnt && i * p[j] <= M;j++)//一定要判斷i*p[j]<=m,保證陣列不會爆 { b[i * p[j]] = 0;//p[j]儲存的是素數,i*p[j]為某素數的倍數,這個數一定不是素數(這是為了減少迴圈次數,縮短時間) if (i % p[j] == 0)break;//假如i是某個素數的倍數,就不用進行迴圈了(這也是為了縮短時間)
} } } int main() { k();//因為前面是全域性變數所以使用函式後面能夠呼叫 int n; cin >> n; for(int i=1;i<=n;i++) { int m; long long int sum = 0; cin >> m; for (int i = 1;i <= cnt;i++) { if(p[i]<=m) sum = (sum + p[i]) % mod;//素數累加就好了,大家都會 } cout << sum << endl; } return 0; }

正在更新中......

製作:BDT20040