/* 孪生素数: 如果n和n+2都是素数,则称他们是孪生素数。输入m,输出两个数均不超过m的最大孪生素数。5<=m<=10000。例如m=20时答案是17,19,m=1000时答案是881,883 */ /* 关键: 1 用素数筛选法先预处理,默认刚开始全为素数,然后对素数的倍数标记为非素数, for(int j = i*i ; j <= 10000 ; j += i){iPrimeArr[j] = 1;} 2 通过开根号判断素数时,可以用floor,注意浮点数加上0.5,int iRadical = floor(sqrt(n*1.0) + 0.5); 3 可以用assert()对输入的合法性进行校验,assert(n >= 5 && n <= 10000);void assert(int exp),如果表达式的值为0则退出。 */ #include <stdio.h> #include <stdlib.h> #include <math.h> #include <string.h> #include <assert.h> //#include <memory.h> #define MAXSIZE 10000 + 1 //预处理,进行素数筛选法,求出素数,然后从m开始向后逆推 bool isPrime(int n) { //判断数字是否小于等于0 assert(n > 0); if(1 == n) { return false; } //int iRadical = (int)sqrt(n*1.0);//radical根号,根据浮点数运算丢失精度,这里加上0.5 int iRadical = floor(sqrt(n*1.0) + 0.5); bool is_prime = true; for(int i = 2 ; i <= iRadical ; i++) { if( n % i == 0) { is_prime = false; break; } } return is_prime; } void findPrime(int m) { //预处理 //bool bPrimeArr[MAXSIZE] = {true};//初始化默认均为素数 int iPrimeArr[MAXSIZE];//初始化默认都为素数 memset(iPrimeArr,0,sizeof(iPrimeArr)); for(int i = 2 ; i <= 10000 ; i++) { if(iPrimeArr[i] == 0)//如果是素数,就将其倍数标记为非素数 { for(int j = i*i ; j <= 10000 ; j += i) { iPrimeArr[j] = 1; } } } //逆推,求孪生素数 for(int k = m ; k >= 5; k--) { if(iPrimeArr[k-2] == 0 && iPrimeArr[k] == 0) { printf("%d %d\n",k-2,k); break; } } } void findPrime2(int n) { assert(n >= 5 && n <= 10000); for(int i = n-2 ; i >= 3; i--) { if(isPrime(i) && isPrime(i+2)) { printf("%d %d\n",i,i+2); break; } } } int main(int argc,char* argv[]) { int m; scanf("%d",&m); //findPrime(m); findPrime2(m); system("pause"); return 0; }