/*
孪生素数:
如果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
#include
#include
#include
#include
//#include
#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;
}