题目

题目描述

题目就是给定一个区间[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. spring cloud 入门系列:总结

    从我第一次接触Spring Cloud到现在已经有3个多月了,当时是在博客园里面注册了账号,并且看到很多文章都在谈论微服务,因此我就去了解了下,最终决定开始学习Spring Cloud.我在一款阅读A ...

  2. C程序员必读的 3 本书

    C程序员必读的 3 本书 原创: Martin 老师  公众号:零基础零障碍学习C语言 勿用质疑,今天来看这篇文章的朋友都是准备学好C语言的朋友,大家想学好C语言的迫切性,就好比Martin老师等着元 ...

  3. gitlab+jenkins持续集成(三)

    构建: 需要将jenkins服务器上  jenkins用户的公钥发送给  目标服务器的gs用户,使得在jenkins上能用gs免密登录目标服务器 复制密钥到目标机器上(需要登录到的机器) ssh-co ...

  4. vue 组件-父组件传值给子组件

    父组件通过属性,传值给子组件,子组件通过,props数组里的名称来接受父组件传过来的值. HTML部分: <div id="app"> <tmp1 :parent ...

  5. SQL面经汇总

    转载链接:https://www.nowcoder.com/discuss/95812 目前的打算是还要写一个假设检验的汇总和机器学习的汇总. 之前写的概率论汇总: https://www.nowco ...

  6. js 的filter()方法

    filter()方法使用指定的函数测试所有元素,并创建一个包含所有通过测试的元素的新数组. filter()基本语法: arr.filter(callback[, thisArg]) filter() ...

  7. Tomcat ngxin 反向代理

    tomcat nginx 反向代理 安装nginx yum直接安装 yum install nginx –y 也可以编译安装 这是用编译安装,新手可以用yum安装 配置文件在 /etc/nginx/c ...

  8. 7行Python代码的人脸识别

    随着去年alphago 的震撼表现,AI 再次成为科技公司的宠儿.AI涉及的领域众多,图像识别中的人脸识别是其中一个有趣的分支.百度的BFR,Face++的开放平台,汉王,讯飞等等都提供了人脸识别的A ...

  9. vim搭建C编程IDE

    曾经在一篇关于vim技巧的文章里有一句话:"世界上只有三种编辑器,EMACS.VIM和其它." 我不知道这是不是太过于绝对了,但是从我所看到的每一篇linux下编程以及文字编辑的文 ...

  10. datetime类型转换

    Select CONVERT(varchar(100), GETDATE(), 8):14:53:14 Select CONVERT(varchar(100), GETDATE(), 9): 06  ...