Description:
判断一个数是否为对称三位数素数。 所谓“对称”是指一个数,倒过来还是该数。例如,375不是对称数,因为倒过来变成了573。Time Limit:1000MS Memory Limit:32768K
Input:
输入数据含有不多于50个的正整数(0<n<2^32)。Output:
对于每个n,如果该数是对称三位数素数,则输出“Yes”,否则输出“No”。每个判断结果单独列一行。Sample Input:
11 101 272
Sample Output:
No
Yes
No
题解:
素数即质数,除了1和它本身,不能被其他自然数整除,2是最小的素数。
一开始的想法太幼稚了,居然认为不能被2、3、5、7整除的数就是素数,而事实上素数至少不能被比自己小的数整除。
因此,本题采用筛选法判断素数,以1,000,000之内的数为例,先开一个大小为1,000,0005的数组(多出来的5是为了防止暴栈)。在这里我们约定,若p[i]=0,则i是素数;若p[i]=1,则i是合数。首先,将p中的元素全部初始化为0,即默认全部为素数。然后将p中下标为i的倍数的元素全部置为1,因为素数的任意倍数都是合数。
注意:这里p[j]=1的操作是从i*i开始进行,而不是从i+i开始,那么i+i到i*i之间的数是不是被漏判了呢?其实某个比i小的数已经做过这个判断了,因为必定存在一个数x<i,使得 i+i<=x*n<=i*i (n>=x). 所以这样的算法更加高效。
接下来就是判断这个三位素数是否是对称的了,采用一种通用方法,百位数字=n/100 (因为n是整数,所以除法得到的小数被略去),个位数字=n%10,若n/100==n%10,则该素数对称。
下面就是代码实现阶段啦,这里用到了memset函数,通常用于初始化新申请的内存,需要引入头文件<cstring>.
其函数原型为:
void *memset(void *s, int ch, size_t n);
函数解释:将s中前n个字节 (typedef unsigned int size_t )用 ch 替换并返回 s.
#include <iostream>
#include <cmath>
#include <cstring>
using namespace std;
int p[1000005];
void IsPrime();
int main()
{
IsPrime();
int n;
while(cin>>n)
{
if(n<100||n>999) cout<<"No"<<endl;
else
{
if (p[n]==0)
{
if(n/100==n%10) cout<<"Yes"<<endl;
else cout<<"No"<<endl;
}
else cout<<"No"<<endl;
}
}
return 0;
}
void IsPrime()
{
memset(p,0,sizeof(p));
p[0]=1;
p[1]=1;
for(int i=2;i<=sqrt(1000000);i++)
if(p[i]==0)
{ //合数的最小素因子一定不超过它的平方根
for(int j=i*i;j<=1000000;j+=i)
p[j]=1;
}
}