题目

题目描述

题目就是给定一个区间[a,b](5 <= a < b <= 100,000,000)),我们需要找到这个区间内所有既是回文串又是素数的数字。

输入样例

5 500

输出样例

5
7
11
101
131
151
181
191
313
353
373
383

解题思路

因为数据范围特别大,如果我们直接枚举所有的素数然后再判断是不是回文串的话肯定会超时。在题目的下面有hints,其中就告诉我们要逆向思维,既然我们枚举素数太多了,那么我们就可以先枚举出所有可能的回文串(这个数量比较少),然后再判断回文串是不是素数。下面就直接模拟这个过程就好了,在写代码的时候,主要是枚举回文串比较费劲,要细心一点。

解题代码

/*
ID: yinzong2
PROG: pprime
LANG: C++11
*/
#define MARK
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; int len, alen, blen;
char astr[12],bstr[12], str[12]; bool isPrime() {
int x = 0;
int temp = 1;
// 先转化为int型整数,然后再判断是否是素数
for (int i = len-1; i >= 0; --i) {
x += (temp*(str[i]-'0'));
temp *= 10;
}
int bound = (int)sqrt(x*1.0);
for (int i = 2; i <= bound; ++i) {
if (x%i == 0) {
return false;
}
}
return true;
} void judge() {
// 保证要我们要求的区间内
// 如果回文串的长度位于alen与blen之间,那么就代表已经是位于区间内了
if (len == alen && strcmp(str, astr) < 0) return ;
if (len == blen && strcmp(str, bstr) > 0) return ;
if (isPrime()) {
cout << str << endl;
}
} // cur用来记录现在产生的是回文串的第几位
void makePalindromes(int cur) {
if (cur == len/2) {
if (len%2 == 0) { // 产生偶数长度的
str[len] = '\0';
judge();
} else { // 产生奇数长度的回文串,中间的那个位置可以为任意数字
for (int i = 0; i <= 9; ++i) {
str[cur] = i+'0';
str[len] = '\0';
judge();
}
}
return ;
}
if (cur == 0) { // 在规定了长度的情况下,首位不能为0
for (int i = 1; i <= 9; ++i) {
str[cur] = i+'0';
str[len-1-cur] = str[cur]; // 两端对称
makePalindromes(cur+1);
}
} else {
for (int i = 0; i <= 9; ++i) {
str[cur] = i+'0';
str[len-1-cur] = str[cur];
makePalindromes(cur+1);
}
}
} int main() {
#ifdef MARK
freopen("pprime.in", "r", stdin);
freopen("pprime.out", "w", stdout);
#endif // MARK
while (~scanf("%s%s", astr, bstr)) {
alen = strlen(astr);
blen = strlen(bstr);
// 枚举所有可能长度的回文串
for (len = alen; len <= blen; ++len) {
makePalindromes(0);
}
}
return 0;
}

官方题解

官方总共给出了四种代码,但是我觉得前两种代码是比较好理解的。具体的思路在这里,其中第二种方法相对于第一种方法有一个很妙的剪枝。

官方代码1

#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <stdlib.h> FILE *fout;
long a, b; int
isprime(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;
} void
gen(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);
} void
genoddeven(int lo, int hi)
{
int i; for(i=lo; i<=hi; i++)
gen(i, 1); for(i=lo; i<=hi; i++)
gen(i, 0);
} void
generate(void)
{
genoddeven(1, 9);
genoddeven(10, 99);
genoddeven(100, 999);
genoddeven(1000, 9999);
} void
main(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);
}

官方代码2

#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <stdlib.h> FILE *fout;
long a, b; int
isprime(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;
} void
gen(int i)
{
char buf[30];
char *p, *q;
long n; sprintf(buf, "%d", i); p = buf+strlen(buf);
q = p - 1; while(q > buf)
*p++ = *--q;
*p = '\0'; n = atol(buf);
if(a <= n && n <= b && isprime(n))
fprintf(fout, "%ld\n", n);
} void
generate(void)
{
int i;
for (i = 1; i <= 9; i++)
gen(i); if(a <= 11 && 11 <= b)
fprintf(fout, "11\n"); for (i = 10; i <= 9999; i++)
gen(i);
} void
main(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);
}

USACO Section 1.5 Prime Palindromes 解题报告的更多相关文章

  1. USACO Section 1.3 Prime Cryptarithm 解题报告

    题目 题目描述 牛式的定义,我们首先需要看下面这个算式结构: * * * x * * ------- * * * <-- partial product 1 * * * <-- parti ...

  2. USACO Section 1.2 Dual Palindromes 解题报告

    题目 题目描述 有一些数(如 21),在十进制时不是回文数,但在其它进制(如二进制时为 10101)时就是回文数. 编一个程序,从文件读入两个十进制数N.S.然后找出前 N 个满足大于 S 且在两种以 ...

  3. USACO Section1.5 Prime Palindromes 解题报告

    pprime解题报告 —— icedream61 博客园(转载请注明出处)--------------------------------------------------------------- ...

  4. USACO Section 1.4 Arithmetic Progressions 解题报告

    题目 题目描述 现在给你一个数集,里面的数字都是由p^2+q^2这种形式构成的0 <= p,q <= M,我现在需要你在其中找出一个长为N的等差数列,数列中的第一个数字为a,公差为b,当你 ...

  5. USACO Section 1.3 Combination Lock 解题报告

    题目 题目描述 农夫John的牛从农场逃脱出去了,所以他决定用一个密码锁来把农场的门锁起来,这个密码锁有三个表盘,每个表盘都是环形的,而且上面刻有1~N,现在John设了一个开锁密码,而且这个锁的设计 ...

  6. USACO Section 1.3 Barn Repair 解题报告

    题目 题目描述 某农夫有一个养牛场,所有的牛圈都相邻的排成一排(共有S个牛圈),每个牛圈里面最多只圈养一头牛.有一天狂风卷积着乌云,电闪雷鸣,把牛圈的门给刮走了.幸运的是,有些牛因为放假,所以没在自己 ...

  7. USACO Section 1.3 Mixing Milk 解题报告

    题目 题目描述 Merry Milk Makers 公司的业务是销售牛奶.它从农夫那里收购N单位的牛奶,然后销售出去.现在有M个农夫,每个农夫都存有一定量的牛奶,而且每个农夫都会有自己的定价.假设所有 ...

  8. USACO Section 1.2 Palindromic Squares 解题报告

    题目 题目描述 输入一个基数B,现在要从1到300之间找出一些符合要求的数字N.如果N的平方转换成B进制数之后是一个回文串,那么N就符合要求.我们将N转换成B进制数输出,然后再将N的平方转换成B进制数 ...

  9. USACO Section 1.2 Milking Cows 解题报告

    题目 题目描述 有3个农夫每天早上五点钟便起床去挤牛奶,现在第一个农夫挤牛奶的时刻为300(五点钟之后的第300个分钟开始),1000的时候结束.第二个农夫从700开始,1200结束.最后一个农夫从1 ...

随机推荐

  1. Unity Shader 学习之旅之SurfaceShader

    Unity Shader 学习之旅之SurfaceShader unity shader 图形图像  如果大地的每个角落都充满了光明 谁还需要星星,谁还会 在夜里凝望 寻找遥远的安慰——江河 官方文档 ...

  2. 电梯调度 结对项目开发(郭林林&胡潇丹)

    (一)需求分析: 上升,下降,开门,关门: 超过负载以后发出警报,下去乘客: 电梯出现故障后,电梯停止: 电梯楼层的输入框可以同时指定所要到的楼层,也是楼层的显示框: 电梯同时记录多个状态,即为到达多 ...

  3. Protocol buffer的使用案例

    Protocolbuffer(以下简称PB)是google 的一种数据交换的格式,它独立于语言,独立于平台.google 提供了多种语言的实现:java.c#.c++.go 和 python,每一种实 ...

  4. PHP.ini 能不能加载子配置文件 ?

    答案是不能,php这个地方用的是另一个方案解决的 编译的时候 用这个参数 --with-config-file-scan-dir指定一个目录 然后在这个目录里面加载ini   https://www. ...

  5. date命令详解

    基础命令学习目录首页 原文链接:https://www.cnblogs.com/qmfsun/p/4598650.html date "+今天是%Y-%d-%m,现在是%H:%M:%S&qu ...

  6. dubbo支持协议及具体对比

    对dubbo的协议的学习,可以知道目前主流RPC通信大概是什么情况,本文参考dubbo官方文档 http://dubbo.io/User+Guide-zh.htm dubbo共支持如下几种通信协议: ...

  7. 将React Native 集成进现有OC项目中(过程记录) 、jsCodeLocation 生成方式总结

    将RN集成到现有OC项目应该是最常见的,特别是已经有OC项目的,不太可能会去专门搞个纯RN的项目.又因为RN不同版本,引用的依赖可能不尽相同,所以特别说明下,本文参考的文档是React Native ...

  8. Beta发布文案+美工

    团队名称:探路者 1蔺依铭:http://www.cnblogs.com/linym762/(组长) 2张恩聚:http://www.cnblogs.com/zej87/ 3米赫:http://www ...

  9. bing词典vs有道词典对比测试报告——功能篇之细节与用户体验

    之所以将细节与用户体验放在一起讨论,是因为两者是那么的密不可分.所谓“细节决定成败”,在细节上让用户感受方便.舒适.不费心而且温馨,多一些人文理念,多一些情怀,做出来的产品自然比其他呆板的产品更受欢迎 ...

  10. JAVA第一次实验 ——凯撒密码

    课程:Java程序设计 班级:1352 姓名:黄伟业 学号:20135215 成绩:            指导教师:娄嘉鹏  实验日期:2015.4.15 实验密级: 预习程度:  实验时间:19: ...