USACO Section 1.5 Prime Palindromes
来源:互联网 发布:水利设计软件 编辑:程序博客网 时间:2024/05/17 06:02
题目原文
Prime Palindromes
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 <= 100,000,000); both a and b are considered to be within the range .
PROGRAM NAME: pprime
INPUT FORMAT
Line 1:Two integers, a and bSAMPLE INPUT (file pprime.in)
5 500
OUTPUT FORMAT
The list of palindromic primes in numerical order, one per line.SAMPLE OUTPUT (file pprime.out)
5711101131151181191313353373383
分析
题目意思很简单,给定一个范围a~b(一亿以内),求出该范围内的所有回文质数。这就涉及到两种特殊数字的判断,质数和回文数。
质数的判断可以按如下的代码实现:
bool isPrime(int n){if(n==0 || n==1)return false;int d=2;while(d*d<=n){if(n%d++==0)return false;}return true;}这里注意的是,d不需要从2到n-1,到sqrt(n)就可以了。
而判断回文,在之前的题目中也使用过,可以用下面这个函数判断
bool isPalin(int n) { vector<int> str;while(n>0){str.push_back(n%10);n = n / 10;}int half = str.size()/2; bool same = true; for (int i=0;i!=half;i++) { same = same && str[i] == str[str.size()-i-1]; if(!same) return false;} if(same) return true; }
因此要换一个思路来做。
首先,所有的偶数肯定不是质数,应该排除;另外,回文的判断过于复杂,应该直接生成具有回文性质的数,而不是事先有数再去判断。题目中的提示(hint2)指出,根据回文的性质,只需要枚举一般的回文数就可以了,如下:
/* generate five digit palindrome: */for (d1 = 1; d1 <= 9; d1+=2) {/* only odd; evens aren't so prime */ for (d2 = 0; d2 <= 9; d2++) { for (d3 = 0; d3 <= 9; d3++) { palindrome = 10000*d1 + 1000*d2 +100*d3 + 10*d2 + d1; ... deal with palindrome ...} }}由于要排除所有偶数,所以d1每次加2,而不是加1。
通过上述的方法,就可以大大减少判断的数据量,提高运行速度。而除此之外,还可以根据一个数学性质来排除一部分数,即偶数长度的回文一定能被11整除,所以除了11本身,其他偶数长度的回文都不是质数,这就又可以排除掉一部分。
提交代码
/*ID: Aaron CaiPROG: pprimeLANG: C++*/#include <iostream>#include <fstream>#include <vector>#include <algorithm>#include <string>using namespace std;bool isPrime(int n){if(n==0 || n==1)return false;int d=2;while(d*d<=n){if(n%d++==0)return false;}return true;}bool isPalin(int n) { vector<int> str;while(n>0){str.push_back(n%10);n = n / 10;}if(str.size()%2==0)return false;int half = str.size()/2; bool same = true; for (int i=0;i!=half;i++) { same = same && str[i] == str[str.size()-i-1]; if(!same) return false;} if(same) return true; }int main(){ifstream fin("pprime.in");ofstream fout("pprime.out");int a,b;fin >> a >> b;for (int d=a;d<12;d++){if(isPrime(d))fout << d << endl;}for (int d1=1;d1<10;d1+=2){for (int d2=0;d2<10;d2++){if(isPrime(100*d1 + 10 * d2 + d1) && 100*d1 + 10 * d2 + d1>=a && 100*d1 + 10 * d2 + d1<=b)fout << 100*d1 + 10 * d2 + d1 << endl;}}for (int d1=1;d1<10;d1+=2){for (int d2 = 0;d2<10;d2++){for (int d3 =0;d3<10;d3++){if(isPrime(10000*d1 + 1000*d2 + 100 * d3 + 10*d2+d1) && 10000*d1 + 1000*d2 + 100 * d3 + 10*d2+d1>=a && 10000*d1 + 1000*d2 + 100 * d3 + 10*d2+d1<=b)fout << 10000*d1 + 1000*d2 + 100 * d3 + 10*d2+d1 << endl;}}}for (int d1=1;d1<10;d1+=2){for (int d2=0;d2<10;d2++){for (int d3=0;d3<10;d3++){for (int d4=0;d4<10;d4++){if(isPrime(1000000*d1+d1+100000*d2+10*d2 + 10000*d3+100*d3 + 1000 * d4) && 1000000*d1+d1+100000*d2+10*d2 + 10000*d3+100*d3 + 1000 * d4>=a && 1000000*d1+d1+100000*d2+10*d2 + 10000*d3+100*d3 + 1000 * d4<=b)fout << 1000000*d1+d1+100000*d2+10*d2 + 10000*d3+100*d3 + 1000 * d4 << endl;}}}}return 0;}
提交结果
TASK: pprimeLANG: C++Compiling...Compile: OKExecuting... Test 1: TEST OK [0.051 secs, 3500 KB] Test 2: TEST OK [0.035 secs, 3500 KB] Test 3: TEST OK [0.057 secs, 3500 KB] Test 4: TEST OK [0.041 secs, 3500 KB] Test 5: TEST OK [0.035 secs, 3500 KB] Test 6: TEST OK [0.030 secs, 3500 KB] Test 7: TEST OK [0.049 secs, 3500 KB] Test 8: TEST OK [0.054 secs, 3500 KB] Test 9: TEST OK [0.092 secs, 3500 KB]All tests OK.
#include <stdio.h>#include <string.h>#include <assert.h>#include <stdlib.h>FILE *fout;long a, b;intisprime(long n){ long i; if(n == 2)return 1; if(n%2 == 0)return 0; for(i=3; i*i <= n; i+=2)if(n%i == 0) return 0; return 1;}voidgen(int i, int isodd){ char buf[30]; char *p, *q; long n; sprintf(buf, "%d", i); p = buf+strlen(buf); q = p - isodd; while(q > buf)*p++ = *--q; *p = '\0'; n = atol(buf); if(a <= n && n <= b && isprime(n))fprintf(fout, "%ld\n", n);}voidgenoddeven(int lo, int hi){ int i; for(i=lo; i<=hi; i++) gen(i, 1); for(i=lo; i<=hi; i++) gen(i, 0);}voidgenerate(void){ genoddeven(1, 9); genoddeven(10, 99); genoddeven(100, 999); genoddeven(1000, 9999);}voidmain(void){ FILE *fin; fin = fopen("pprime.in", "r"); fout = fopen("pprime.out", "w"); assert(fin != NULL && fout != NULL); fscanf(fin, "%ld %ld", &a, &b); generate(); exit (0);}官方给出了好多个参考答案,但是大同小异,就不都贴出来了。
其实本题还存在一个地方可以优化,那就是大质数的判断算法,提交的代码中使用的质数判断算法对于较大的数字运行速度比较低,还有改进的空间。
THE END
0 0
- USACO Section 1.5 Prime Palindromes
- USACO Section 1.5 Prime Palindromes
- USACO Section 1.5 Prime Palindromes
- USACO Section 1.5 Prime Palindromes
- USACO section 1.5.2 Prime Palindromes
- USACO section 1.5 Prime Palindromes(模拟)
- [USACO Section 1.5] Prime Palindromes (模拟)
- Section 1.5 Prime Palindromes
- USACO-Section 1.5 Prime Palindromes(Miller-Rabin)
- USACO--1.5Prime Palindromes
- USACO 1.5 Prime Palindromes
- USACO 1.5-Prime Palindromes
- USACO 1.5.2 prime palindromes
- [USACO 1.5.2] Prime Palindromes
- [搜索]USACO-1.5-Prime Palindromes
- USACO 1.5 Prime Palindromes (pprime)
- USACO Section 1.5 Prime Palindromes - 换个搜索顺序效率会提高不少
- USACO 1.5.2 Prime Palindromes 回文质数
- Log4net测试笔记
- iOS中代码支持多国语言切换的实现(Xcode5+iOS7)
- 装饰者模式
- 一款模拟养成类游戏的策划大纲
- Java IO流笔记1
- USACO Section 1.5 Prime Palindromes
- Port Forwarding & Port Triggering
- 王立平--svn服务器搭建
- 设计模式——单例模式(Singleton)
- 虚拟主机,你那些不知道的事
- hdu 5023 A Corrupt Mayor's Performance Art 2014 ACM/ICPC Asia Regional Guangzhou Online
- UVa 202 - Repeating Decimals
- java解析Xml 保存格式设置
- android小图标P图经验