输入格式:
输入在一行给出正整数N。
输出格式:
在一行中输出不超过N的满足猜想的素数对的个数。
输入样例:
20
输出样例:
4
我的思路及代码
题目分析:
素数:(质数prime number)定义为在大于1的自然数中,除了1和它本身以外不再有其他因数,素数有无穷多个
例如2 (他的因数只有1和2本身) 3(因数只有1和3本身)
前20个素数有2, 3, 5, 7, 11, 13, 17,19
而题目就是给定一个N,例如样例20 然后输出在0-20内满足猜想的素数对个数,猜想就是相邻的两个素数的差为2 例如2, 3, 5, 7, 11, 13, 17,19这里面差为2的素数对有(3,5) (5,7) (11,13) (17,19) 共4个
#思路:
N的限制最大为1e5,我们可以先开一个vector容器,然后从0-1e5找到所有素数放入容器,再对容器进行遍历,如果满足v[i+1]-v[i]==2的话就是满足猜想,那么就cnt++,最后输出cnt就行 可以发现这是一种比较暴力的做法,如果N太大了就不行
关于
bool primes(int x)
{
if (x < 2) return false;
for (int i = 2; i <= x / i; i ++ )
if (x % i == 0) return false;
return true;
}
为什么for循环是从2到 i<=x/i; 这个是可以模拟一下的,例如36,他的因子有(2 18 3 12 4 9 6 6) 最多只会遍历到18 所以当i=2时 我们就可以将范围缩到i<=18 再往后面遍历没啥意义了
#代码:
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int n;
bool primes(int x)
{
if (x < 2) return false;
for (int i = 2; i <= x / i; i ++ )
if (x % i == 0) return false;
return true;
}
//素数=质数 2, 3, 5, 7, 11, 13, 17, 19, 23, 29
int main()
{
cin >> n;
vector<int> v; //容量为1e5+10的容器 用来存放素数
//d1=p2-p1(3-2)=1 d2=p3-p2(5-3)=2 d3=p4-p3(7-5)=2
//d4=p5-p4(11-7)=4 d5=p6-p5(13-11)=2 d6=p7-p6(19-17)=2
//从0到1e5+10查找素数并放入vector
for (int i = 0; i <= 1e5 + 10; i ++ )
if (primes(i)) v.push_back(i);
int cnt = 0; //计算不超过N的满足猜想的素数对的个数
for (int i = 0; i < v.size(); i ++ )
{ //2, 3, 5, 7, 11, 13, 17, 19, 23, 29
if (v[i + 1] > n) break;
int res = v[i + 1] - v[i];
if (res == 2) cnt ++;
}
cout << cnt;
return 0;
}
柳神的思路及代码
#思路:
对于数字a,i从2到根号a,如果a能够被其中⼀个i整除,说明i 不是素数,return false,否则说明a是素数return true;对于输⼊数据N,for循环中的i从5到N依次判断 i-2和i是否是素数,如果都是素数,则统计个数的cnt++,最后输出cnt即可
相比我的代码改进了后面部分 从5开始到N (5,7是第一个猜想素数对) 判断相差为2的两个数是否为素数 是的话cnt++
#代码:
#include <iostream>
using namespace std;
bool isprime(int a) {
for (int i = 2; i * i <= a; i++)
if (a % i == 0) return false;
return true;
}
int main() {
int N, cnt = 0;
cin >> N;
for (int i = 5; i <= N; i++)
if (isprime(i-2) && isprime(i)) cnt++;
cout << cnt;
return 0;
}