int i;for(i=0; ;) 与 for(int i=0 ; ;) 两种定义循环变量的方式的区别:
the difference between int i;for(i = 0;;) and for(int i = 0;;):
- 两种均可,前者i在for循环外部定义,则i的值在程序未结束之前就一直存在,i所占的内存空间直到程序结束时才释放;后者的i在for循环内部定义,则当for循环结束时,i所占的内存空间就被释放了。一般建议用后者的方式,因为当程序较大时,前者更占内存,这样程序在运行时CPU的负担就更大,内存溢出的风险更大。
————————————————————————————————————————
Main Problem:PAT 1007
Keywords:prime;twin prime(孪生素数)
three methods to judge a number is a prime or not
1 这里特殊处理了一下小于等于3的数,因为小于等于3的自然数只有2和3是质数。然后,我们只需要从2开始,一直到小于其自身,依次判断能否被n整除即可,能够整除则不是质数,否则是质数。
public static boolean isPrime(int n){
if (n <= 3) {
return n > 1;}for(int i = 2; i < n; i++){
if (n % i == 0) {
return false;}}return true;
- 假如n是合数,必然存在非1的两个约数p1和p2,其中p1<=sqrt(n),p2>=sqrt(n)。由此我们可以改进上述方法优化循环次数。如下:
public static boolean isPrime(int n) {
if (n <= 3) {
return n > 1;}int sqrt = (int)Math.sqrt(n);for (int i = 2; i <= sqrt; i++) {
if(n % i == 0) {
return false;}}return true;
}
3质数还有一个特点,就是它总是等于 6x-1 或者 6x+1,其中 x 是大于等于1的自然数。
相关定理证明:
定理1:当n≥5时,如果n为素数,那么n%6=1或n%6=5。即n一定出现在6x(x≥1)的两侧。
证明:当x≥1时,有如下表示方法:
…… 6x-1,6x,6x+1,6x+2,6x+3,6x+4,6x+5,6(x+1),6(x+1)+1 ……
观察得,当n≥5时,不在6x(x≥1)两侧的数为6x+2,6x+3,6x+4,……,即2(3x+1),3(2x+1),2(3x+2)……。
显然,它们一定不是素数。
所以当n≥5时,素数一定出现在6x(x≥1)的两侧。
这里要注意的是,不在6x(x≥1)两侧的肯定不是素数,但在6x(x≥1)两侧的并不是一定就是素数。
所以此时需要对6x(x≥1)两侧数据进行判断。常见方法是采用普通sqrt(n)版判断素数方法(步长取6)。
定理2:若n≥6且n-1和n+1为孪生素数,那么n一定是6的倍数。
证明:所谓孪生素数指的是间隔为2的相邻素数。
∵ n-1和n+1是素数 ┈┈┈┈┈ ①
∴ n-1和n+1是奇数
∴ n是偶数,即n是2的倍数 ┈┈┈┈┈ ②
此外,假设n不是3的倍数,则得:n=3x+1 或 n=3x+2,
如果n=3x+1,则n-1=3x,此式存在n-1是偶数的可能,与①违背,故n≠3x+1;
如果n=3x+2,则n+1=3(x+1),此式存在n+1是偶数的可能,与①违背,故n≠3x+2;
∴n不是3的倍数的假设不成立,故得n是3的倍数,又结合②得结论:
n是6的倍数。
public static boolean isPrime(int num) {
if (num <= 3) {
return num > 1;}// 不在6的倍数两侧的一定不是质数if (num % 6 != 1 && num % 6 != 5) {
return false;}int sqrt = (int) Math.sqrt(num);for (int i = 5; i <= sqrt; i += 6) {
if (num % i == 0 || num % (i + 2) == 0) {
return false;}}return true;
}
To be resolved problems:
- int 4 bytes (32 bits) - count primes among [0,2312^{31}231-1] and print
them out. - long long 8 bytes(64bits) - count primes among [0,2642^{64}264-1] and
print them out.
Original AC Code:2021年6月4日11:00:40
#include <cstdio>
#include <iostream>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
#define M 100000
bool isprime( int number)
{
if(number==1) return false;if(number==2||number ==3) return true;else{
for(int i = 2 ; i <= sqrt(number) ; i ++){
if(number%i == 0 ) return false;}}return true;
}
int main()
{
int n;cin>>n;int j=0;int prime[M];int count = 0 ;memset(prime,0,M*sizeof(int));for(int i = 1 ;i <n+1 ;i ++){
if(isprime(i)){
prime[j++]=i;// cout<<i<<endl;}}for(int k = 1;k < j ; k ++ ){
if(prime[k]-prime[k-1]==2)count ++;}cout<<count<<endl;return 0 ;
}
————————————————
版权声明:本文部分内容来自 CSDN博主「hnjzsyjyj」、阿飞__的原创文章,遵循CC 4.0 BY-SA版权协议。
博主「hnjzsyjyj」原文链接:https://blog.csdn.net/hnjzsyjyj/article/details/101234139
博主 阿飞__原文链接:https://blog.csdn.net/afei__/article/details/80638460