【PAT】1007 review

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;

  1. 假如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, 2 31 2^{31} 231-1] and print
    them out.
  • long long 8 bytes(64bits) - count primes among [0, 2 64 2^{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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
根据引用\[1\]和引用\[2\]的代码,这是一个关于判断素数和计算素数对的问题。代码中使用了循环和条件判断来判断一个数是否为素数,并计算相邻素数之间差为2的素数对的数量。具体的代码逻辑如下: 1. 首先,通过输入一个正整数n来确定素数的范围。 2. 然后,使用循环从3开始遍历到n,判断每个数是否为素数。 3. 在判断素数的过程中,使用了一个内层循环和条件判断来判断一个数是否能被其他数整除,如果能整除则不是素数。 4. 如果一个数通过了判断是素数,则将其存入数组a中。 5. 最后,再次遍历数组a,判断相邻素数之间的差是否为2,如果是则计数器sum加1。 6. 最后输出sum的值,即为相邻且差为2的素数对的数量。 根据题目要求,输入样例为20,输出样例为4,即在1到20的范围内,存在4对相邻且差为2的素数。因此,根据给定的代码,输出结果应为4。 #### 引用[.reference_title] - *1* [PAT乙级-1007 素数对猜想- C语言实现(代码详解+知识点归纳)](https://blog.csdn.net/m0_61704394/article/details/124017780)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [PAT乙级C语言1007 素数对猜想](https://blog.csdn.net/li_yizhixiaowukong/article/details/88072233)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值