[An AC a day]1004_HIT_ACM

Prime Palindromes

My Tags  (Edit)
  Source : USACO Gateway
  Time limit : 15 sec   Memory limit : 32 M

Submitted : 19582, Accepted : 4395

The number 151 is a prime palindrome because it is both a prime number and a palindrome (it is the same number when read forward as backward). Write a program that finds all prime palindromes in the range of two supplied numbers a and b (5 <= a < b <= 1000,000,000); both a and b are considered to be within the range .

Input

Line 1: Two integers, a and b

Output

The list of palindromic primes in numerical order, one per line.

Sample Input
5 500
Sample Output
5
7
11
101
131
151
181
191
313
353
373
383

#include<stdio.h>
#include<math.h>
#define N 100000

bool isprime(int n);

int main()
{
	int start,end,num;
	scanf("%d%d",&start,&end);
	//判断2位数和1位数
	int chart[11] = {0,1,1,0,1,0,1,0,0,0,1};
	if(start <= 11)
	{
		for(int i = start-1;i<11;i++)
		{
			if((chart[i]) && (i+1>=start) && (i+1<=end))
			{
				printf("%d\n",i+1);
			}
		}
	}
	//判断3位数
	if(end <100)
		return 0;
	if(start <1000)
		for(int i = 1;i<=9;i+=2)
			for(int j = 0;j<=9;j++)
			{
				num = 101*i + 10*j;
				if((isprime(num)) && (num>=start) && (num<=end))
				{
					printf("%d\n",num);
				}
			}
	//判断5位数
	if(end < 10000)
		return 0;
	if(start <100000)
		for(int i = 1;i<=9;i+=2)
			for(int j = 0;j<=9;j++)
				for(int k = 0;k<=9;k++)
				{
					num = 10001*i + 1010*j + 100*k;
					if((isprime(num)) && (num>=start) && (num<=end))
					{
						printf("%d\n",num);
					}
				}
	//判断7位数
	if(end < 1000000)
		return 0;
	if(start < 10000000)
		for(int i = 1;i<=9;i+=2)
			for(int j = 0;j<=9;j++)
				for(int k = 0;k<=9;k++)
					for(int l = 0;l<=9;l++)
					{
						num = 1000001*i + 100010*j + 10100*k + 1000*l;
						if((isprime(num)) && (num>=start) && (num<=end))
						{
							printf("%d\n",num);
						}
					} 
	//判断9位数
	if(end < 100000000)
		return 0;
	for(int i = 1;i<=9;i+=2)
		for(int j = 0;j<=9;j++)
			for(int k = 0;k<=9;k++)
				for(int l = 0;l<=9;l++)
					for(int m = 0;m<=9;m++)
					{
						num = 100000001*i + 10000010*j + 1000100*k +101000*l +10000*m;
						if((isprime(num)) && (num>=start) && (num<=end))
						{
							printf("%d\n",num);
						}
					}
	return 0;
}
bool isprime(int n)
{
	int i;
	for(i = 2;i <= (int)sqrt((double)n); i++)
	{
		if(n % i == 0)
			break;
	}
	if(i == (int)sqrt((double)n)+1)
		return true;
	else
		return false;
}

1、所有位数是偶数的回文数都可以被11整除(位数>2)。因此可以对位数为偶数的回文数忽略。

(注:判断整数是否为11的倍数法:将所有奇数位数字相加减去所有偶数位数字之和,如果可以被11整除,则这个数字是11的整倍数。

2、小于100的可以直接打表得到。

3、得到回文数可以用上文代码所用的方法。



附:能被n整除的数的特征:

1、1是任何整数的约数。

2、若一个整数的末位是0、2、4、6或8,则这个数能被2整除。

3、若一个整数的数字和能被3整除,则这个整数能被3整除。

4、若一个整数的末尾两位数能被4整除,则这个数能被4整除。

5、若一个整数的末位是0或5,则这个数能被5整除。

6、若一个整数能被2和3整除,则这个数能被6整除。

7、若一个整数的个位数字截去,再从余下的数中,减去个位数的2倍,如果差是7的倍数,则原数能被7整除。

如果差太大或心算不易看出是否7的倍数,就需要继续上述「截尾、倍大、相减、验差」的过程,直到能清楚判断为止。

例如,判断133是否7的倍数的过程如下:13-3×2=7,所以133是7的倍数;

又例如判断6139是否7的倍数的过程如下:613-9×2=595 , 59-5×2=49,所以6139是7的倍数,余类推。

这种方法叫“割尾法”.此法还可简化为:从一个数减去7的10倍、20倍、30倍、……到余下一个100以内的数为止,如果余数能被7整除,那么,这个数就能被7整除.

证明过程:设p=a0+a1×10+a2×102+...+a(n-1)×10(n-1)+an×10n

q=a1+a2×10+...+a(n-1)×10(n-2)+an×10(n-1)-2a0

2p+q=21(a1+a2×10+...+an×10(n-1))

又因为21=7×3,所以若p是7的倍数,那么可以得到q是7的倍数。

末三法:这个数的末三位数与末三位以前的数字所组成的数之差(反过来也行)能被7、11、13整除。这个数就能被7、11、13整除例如:1005928末三位数:928,末三位之前:1005  1005-928=77 因为7 | 77,所以7|1005928

简略证明:设一个数为ABCDEF=ABC×1000+DEF=ABC×1001-ABC+DEF=ABC×7×13×11-(ABC-DEF),由此可见只要ABC-DEF能被7整除,则ABCDEF能被7整除。

8、若一个整数的未尾三位数能被8整除,则这个数能被8整除。

9、若一个整数的数字和能被9整除,则这个整数能被9整除。

10、若一个整数的末位是0,则这个数能被10整除。

11、若一个整数的奇位数字之和与偶位数字之和的差能被11整除,则这个数能被11整除。

例如,1234567

1+3+5+7=16
2+4+6=12
16-12=4(不是11的倍数)
所以不能被十一整除

11的倍数检验法也可用上述检查7的「割尾法」处理!过程唯一不同的是:倍数不是2而是1!

12、若一个整数能被3和4整除,则这个数能被12整除。

13、若一个整数的个位数字截去,再从余下的数中,加上个位数的4倍,如果差是13的倍数,则原数能被13整除。

如果差太大或心算不易看出是否13的倍数,就需要继续上述「截尾、倍大、相加、验差」的过程,直到能清楚判断为止。

17、若一个整数的个位数字截去,再从余下的数中,减去个位数的5倍,如果差是17的倍数,则原数能被17整除。

如果差太大或心算不易看出是否17的倍数,就需要继续上述「截尾、倍大、相减、验差」的过程,直到能清楚判断为止。

若一个整数的末三位与3倍的前面的隔出数的差能被17整除,则这个数能被17整除。

19、若一个整数的个位数字截去,再从余下的数中,加上个位数的2倍,如果差是19的倍数,则原数能被19整除。

如果差太大或心算不易看出是否19的倍数,就需要继续上述「截尾、倍大、相加、验差」的过程,直到能清楚判断为止。

若一个整数的末三位与7倍的前面的隔出数的差能被19整除,则这个数能被19整除。

23、若一个整数的末四位与前面5倍的隔出数的差能被23(或29)整除,则这个数能被23整除


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值