USACO Prime Palindroms
2015-02-24 14:11
239 查看
【题意】
给定a,b,求所有p满足p属于[a,b]且p为素数且p为回文数(5<=a,b<=10000000)
【解析】
USACO上评测时可以使用的空间真的不大啊,开到10000000就会爆掉。
还有应该每道题的时间限制都是1s,因为本题超过就算没通过了。
这道题要求三个条件,那就要分层次处理。
[ 方法1 ]
枚举a到b的所有数进行判断。
因为USACO的空间限制,所以素数判定只能用O(n 根号n)的。
很明显会爆时间,但还是附两个代码。
试除法:
欧拉筛法:
[ 方法2 ]
不难发现回文串比素数少,而且知道第i位就可以知道n+1-i位(1个对应位)
所以可以先求出a,b的位数,然后枚举位数,进行b的位数-a的位数+1次搜索,找到所有回文串进行判定。
这里还要预先保存一下mtp
,就是十进制每位的位值。
最后检验的时候,一要判定满足在a到b间,二要判定是素数。
代码如下(正解):
【总结】找到所有满足的数的问题,若有多个限制条件,要么可以想出一种方法直接解决,要么就分层次处理,找到一种时间复杂度最低的就是正解。
给定a,b,求所有p满足p属于[a,b]且p为素数且p为回文数(5<=a,b<=10000000)
【解析】
USACO上评测时可以使用的空间真的不大啊,开到10000000就会爆掉。
还有应该每道题的时间限制都是1s,因为本题超过就算没通过了。
这道题要求三个条件,那就要分层次处理。
[ 方法1 ]
枚举a到b的所有数进行判断。
因为USACO的空间限制,所以素数判定只能用O(n 根号n)的。
很明显会爆时间,但还是附两个代码。
试除法:
/* ID:y2007031 PROG:pprime LANG:C++ */ #include <cstdio> #include <cstring> #include <cstdlib> using namespace std; const int N=10000001; int v ,p[N>>3]; int a,b; int s[20]; int can(int i) { s[0]=0; for (;i;i/=10) s[++s[0]]=i%10; for (int i=1;i<=s[0]>>1;i++) if (s[i]^s[s[0]+1-i]) return 0; return 1; }
欧拉筛法:
int main(void) { freopen("pprime.in","r",stdin); freopen("pprime.out","w",stdout); scanf("%d%d",&a,&b); v[1]=1; for (int i=2;i<=b;i++) { if (!v[i]) p[++p[0]]=i; for (int j=1;j<=p[0];j++) { if (i*p[j]>b) break; v[i*p[j]]=1; if (i%p[j]==0) break; } } for (int i=1;i<=p[0];i++) { if (p[i]<a) continue; if (p[i]>b) break; if (a<=p[i]&&p[i]<=b&&can(p[i])) printf("%d\n",p[i]); } return 0; }
[ 方法2 ]
不难发现回文串比素数少,而且知道第i位就可以知道n+1-i位(1个对应位)
所以可以先求出a,b的位数,然后枚举位数,进行b的位数-a的位数+1次搜索,找到所有回文串进行判定。
这里还要预先保存一下mtp
,就是十进制每位的位值。
最后检验的时候,一要判定满足在a到b间,二要判定是素数。
代码如下(正解):
/* ID:y2007031 PROG:pprime LANG:C++ */ #include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> using namespace std; int a,b,la,lb; int s[40]; int f[40],mtp[40]; void due(int k) { s[0]=0; for (;k;k/=10) s[++s[0]]=k%10; } int check(int k) { if (k<=1) return 0; for (int i=2;i<=(int)sqrt(k);i++) if (k%i==0) return 0; return 1; } void DFS(int dep,int lmt,int now) { if (dep==(lmt>>1)+1) { if (lmt&1) for (int i=0;i<=9;i++) { int t=now+i*mtp[dep]; if (a<=t&&t<=b&&check(now+i*mtp[dep])) printf("%d\n",now+i*mtp[dep]); } else if (a<=now&&now<=b&&check(now)) printf("%d\n",now); return; } for (int i=0;i<=9;i++) { if (dep==1&&!i) continue; DFS(dep+1,lmt,now+i*mtp[dep]+i*mtp[lmt-dep+1]); } } int main(void) { freopen("pprime.in","r",stdin); freopen("pprime.out","w",stdout); scanf("%d%d",&a,&b); due(a),la=s[0]; due(b),lb=s[0]; mtp[1]=1; for (int i=2;i<=lb;i++) mtp[i]=mtp[i-1]*10; for (int i=la;i<=lb;i++) DFS(1,i,0); return 0; }
【总结】找到所有满足的数的问题,若有多个限制条件,要么可以想出一种方法直接解决,要么就分层次处理,找到一种时间复杂度最低的就是正解。
相关文章推荐
- 【模拟】洛谷 P1211 [USACO1.3]牛式 Prime Cryptarithm
- USACO-Section 1.3 Prime Cryptarithm[...]
- USACO--Prime Cryptarithm
- Prime Palindromes(usaco)
- P1217 [USACO1.5]回文质数 Prime Palindromes(求100000000内的回文素数)
- 这压缩,太强了![USACO1.3]牛式 Prime Cryptarithm
- USACO1.5.2 Prime Palindromes (pprime)
- 洛谷 P1218 [USACO1.5]特殊的质数肋骨 Superprime Rib
- 【USACO-Chapter1-1.3】【模拟】Prime Cryptarithm
- USACO section 1.5 Superprime Rib(深搜)
- usaco Prime Cryptarithm
- usaco Prime Palindromes
- usaco Superprime Rib
- USACO1.3.4 Prime Cryptarithm(牛式)
- usaco Prime Palindromes
- USACO Section 1.3 Prime Cryptarithm
- USACO 1.3 Prime Cryptarithm (crypt1)
- USACO Section 1.3: Prime Cryptarithm
- usaco pprime
- USACO之Prime Cryptarithm