对洛谷P1217 [USACO1.5]回文质数 Prime Palindromes 我自己的题解与思考
我真是是太弱了.jpg
/*
题目范围5-100000000
已知1位的数中的回文质数是2,3,5,7(奇怪,只有一位也算回文数?)
偶数位的回文数除11外(特殊处理)均不是回文质数(能被11整除)
故只需要从3,5,7位的数中寻找回文质数(9位只有一亿,而一亿显然不是回文质数)
思路是制造回文数,判断是否在范围内,再判断是否是回文质数
说白了还是列举递推,极麻烦和弱智的办法= =
但我也莫得办法了,研究很久题解都看不懂
果然还是我太弱了orz
*/
#include<stdio.h>
int main()
{
int a,b;
scanf("%d %d",&a,&b);//声明并输入上下限
int i1,i2,i3,i4,i5,n;//i老工具人,n存放回文质数
int m;//判断是否质数
if(a>999) goto L1;
if(a>99999) goto L2;//对下限较高时的处理办法,减少tle的概率(虽然我感觉依然会tle
if(a<=2&&b>=2) printf("2\n");
if(a<=3&&b>=3) printf("3\n");
if(a<=5&&b>=5) printf("5\n");
if(a<=7&&b>=7) printf("7\n");
if(a<=11&&b>=11) printf("11\n");//特殊处理
for(i1=1;i1<=9;i1+=2)
for(i2=0;i2<=9;i2++)
{
m=1;
n=i1*100+i2*10+i1;
if(n<a) continue;
else if(n>b) return 0;//n不在求值范围内的处理办法
for(int x=2;x*x<=n;x++)
{
if(n%x==0)
{
m=0;break;
}
}
if(m==1)
{
printf("%d\n",n);
}
}
L1:for(i1=1;i1<=9;i1+=2)//思路大体相同
for(i2=0;i2<=9;i2++)
for(i3=0;i3<=9;i3++)
{
m=1;
n=i1*10000+i2*1000+i3*100+i2*10+i1;
if(n<a) continue;
else if(n>b) return 0;
for(int x=2;x*x<=n;x++)
{
if(n%x==0)
{
m=0;break;
}
}
if(m==1)
{
printf("%d\n",n);
}
}
L2:for(i1=1;i1<=9;i1+=2)
for(i2=0;i2<=9;i2++)
for(i3=0;i3<=9;i3++)
for(i4=0;i4<=9;i4++)
{
m=1;
n=i1*1000000+i2*100000+i3*10000+i4*1000+i3*100+i2*10+i1;
if(n<a) continue;
else if(n>b) return 0;
for(int x=2;x*x<=n;x++)
{
if(n%x==0)
{
m=0;break;
}
}
if(m==1)
{
printf("%d\n",n);
}
}
return 0;
}
/*事实上,这道题已经在TLE的边缘疯狂试探了
第一次提交因为x*x<=n少打了个等于号而wa了三个
然后我脑子一抽换成了x<n/2....
然后TLExN orz
残酷的事实证明了
算法是个好东西,优化是个好东西
*/