題目
讓我們定義爲:,其中 是第 個素數。顯然有,且對於 有 是偶數。“素數對猜想”認爲“存在無窮多對相鄰且差爲2
的素數”。
現給定任意正整數N
,請計算不超過N
的滿足猜想的素數對的個數。
輸入格式:
輸入在一行給出正整數N
。
輸出格式:
在一行中輸出不超過N
的滿足猜想的素數對的個數。
輸入樣例:
20
輸出樣例:
4
思路&總結
思路(2020-4-9 01:09:00):
1、將N之前的所有素數依次列出來,數一下相鄰兩個素數差值是
2
的總共有多少對。
2、老規矩,素數表使用數組保存,方法類似鍵值對。
*優化點也就是主要的時間消耗點在於素數判斷。百度到直接構造素數表的方法應該較快,也就是在一張表中直接踢掉非素數,剩下的就是素數了,時間複雜度是。答案1是用的循環遍歷判斷有木有因數從而判斷是否爲素數,時間複雜度是。答案2.等下想想寫不寫構造素數表再決定答案2存不存在。
總結(2020-4-9 01:58:11)
1、素數判斷循環上限可以使用
sqrt(n)
提高判斷效率。
2、當需要用到連續的多個素數時,可以用構造素數表的方式提高時間效率。
3、使用sqrt(n)
需要#include <math.h>
。
4、memset(void *str, int c, size_t n)
將str
中當前位置到後面的n
個字節填充c
。可用來做數組初始化.
5、解釋二void *memset(void *s, int v, size_t n)
包含在<string.h>
頭文件中,可以用它對一片內存空間逐字節進行初始化。 這裏s
可以是數組名,也可以是指向某一內在空間的指針;v
爲要填充的值;n
爲要填充的字節數;
6、根據https://blog.csdn.net/u011426016/article/details/86559895 的指示,也只能用來處理某些賦值,最好是char
類型,int
類型容易出錯,計組學的好的可以研究一下這個博客,就是涉及到數據結構的物理存儲和計算機存儲的源碼補碼反碼這些問題了,用來給char
賦初始值就完全某門題。
7、根據百度百科 這個,也講的很仔細,學習。
8、使用memset()
需要#include <string.h>
。
答案1(2020-4-9 01:58:27)
#include <iostream>
#include <math.h>
using namespace std;
int isPrimeNumber(int k)
{
if (k<=1) return 0;
int maxDivisor = (int)sqrt(k);
for (int i = 2; i <= maxDivisor ; i++)
if(k % i == 0)
return 0;
return 1;
}
int main(int argc, char *argv[]) {
int n;
cin >> n;
int primeNumber[n] = {0};
for (int i = 2; i <= n ; i++)
if(isPrimeNumber(i)==1) primeNumber[i] = 1;
int countCouple = 0;
for (int i = 5; i <= n ; i++)
if(primeNumber[i] == 1 && primeNumber[i-2] == 1 )
countCouple ++;
cout << countCouple;
return 0;
}
答案2(2020-4-9 02:19:42)
測試點5運行時間由16ms縮減爲4ms
#include <iostream>
#include <math.h>
using namespace std;
int main(int argc, char *argv[]) {
int n;
cin >> n;
int primeNumber[n+1] = {0};
//createPrimeTable
for (int i = 2; i < n ; i++)
{
if(primeNumber[i]==0)
{
int j = 2;
for(j = 2 ; j * i <= n ; j++)
primeNumber[j*i] = 2;//not prime;
}
}
//count PrimeCouple
int countCouple = 0;
for (int i = 5; i <= n ; i++)
if(primeNumber[i] == 0 && primeNumber[i-2] == 0 )
countCouple ++;
cout << countCouple;
return 0;
}