令 Pi 表示第 i 個素數。現任給兩個正整數 M≤N≤104,請輸出 PM 到 PN 的所有素數。
輸入格式:
輸入在一行中給出 M 和 N,其間以空格分隔。
輸出格式:
輸出從 PM 到 PN 的所有素數,每 10 個數字佔 1 行,其間以空格分隔,但行末不得有多餘空格。
輸入樣例:
5 27
輸出樣例:
11 13 17 19 23 29 31 37 41 43
47 53 59 61 67 71 73 79 83 89
97 101 103
解答:(思路簡單,使用素數表,主要說一下做題發現的內存問題)
#include <cstdio>
const int MAX = 1e6 + 10;
bool isPrimes[MAX]; //1 代表不是素數,0 代表是素數
void make_primes()
{
for(int i = 2;i < MAX;i++)
if(!isPrimes[i])
for(int j = i+i;j < MAX;j += i)
isPrimes[j] = true;
}
int main()
{
//初始化 + 讀入數據:
make_primes();
int l,r;
scanf("%d %d",&l,&r);
//處理 + 輸出:
int num = 0;
int temp = 1;
for(int i = 2;num < r;i++){
if(!isPrimes[i]){
num++;
if(num >= l&&num <= r){
if(temp == 1)
printf("%d",i);
if(temp == 0)
printf(" %d\n",i);
if(temp > 1)
printf(" %d",i);
temp = (temp+1)%10;
}
}
}
return 0;
}
經驗:
在通過 oj 時,報出了段錯誤(我之前定的MAX = 1e4 + 10),是因爲自己想當然地將給出的 N 當成了數據範圍,而 N 指的是截至到第多少個素數,所以範圍一定遠大於 10^4。
在發現段錯誤(我的錯誤的結果是數組越界)之後,我又想當然的是將全局數組的大小開到最大。因爲理論上來說全局數組屬於全局變量,最多可以分得幾GB,我之前一直將1、2GB認爲是比較保守的大小,又因爲平時做 oi 基本上開的都是 int 型數組,所以要再除以 4 ,所以我認爲開 10^8 次方是沒問題的。然而在測評時,我發現我就算開成 10^7 大小還是報了內存超限的錯誤,所以說有的 oj 的編譯器可能並沒有給全局區支持很大的空間,這也讓我以後儘量開 10^7 以內(保險一點)。
但事實上就算10^8次方都可以開的到,我還是犯了錯誤,因爲題目給的時間限制是200ms,也就是0.2s。因爲 2000w 以內的操作數是一定可以保證 1 s內完成,所以要想完成題目要求,要儘量保證操作數在 100w 內,也就是 10^6 內。從這個角度看,我也應該另 MAX = 1e6。所以以後不能覺得自己選的方法高效就大意,不能懶,至少要大致算一下複雜度來估計是否超時。