题目

题目描述

题目就是给定一个区间[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) { // 在规定了长度的情况下,首位不能为0for (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 MARKfreopen("pprime.in", "r", stdin);freopen("pprime.out", "w", stdout);
#endif // MARKwhile (~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);
}

转载于:https://www.cnblogs.com/yinzm/p/7430038.html

USACO Section 1.5 Prime Palindromes 解题报告相关推荐

  1. USACO Training Section 1.3 Calf Flac 解题报告AC代码

    解题报告: 主要方法是生长法,考虑每一位的左右各有多长的回文串,输出最长的那个,比较好想--不过要注意区分字串的奇偶. 其他实现细节看代码里的注释吧-- AC代码: /* ID: yuanmz91 P ...

  2. USACO 3.3.2 Shopping Offers解题报告

    写在前面:因为之前没写的C++的USACO Training的解题报告太多--所以就不写了,要是想要代码可以联系我:xiedong_1993@foxmail.com 这题就是传说中的五维背包,其实写起 ...

  3. USACO 2.2.2 Subset Sums解题报告

    分类:DP,递推,记忆化搜索 作者:ACShiryu 时间:2011-7-15 Subset Sums JRM For many sets of consecutive integers from 1 ...

  4. USACO Section2.1 Hamming Codes 解题报告 【icedream61】

    hamming解题报告 ---------------------------------------------------------------------------------------- ...

  5. USACO Section2.2 Preface Numbering 解题报告 【icedream61】

    preface解题报告 ---------------------------------------------------------------------------------------- ...

  6. USACO Section1.3 Combination Lock 解题报告

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

  7. USACO Section1.5 Superprime Rib 解题报告

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

  8. P1217 [USACO1.5]回文质数 Prime Palindromes——回文质数性质、打表

    [USACO1.5]回文质数 Prime Palindromes 题目描述 因为 151151151 既是一个质数又是一个回文数(从左到右和从右到左是看一样的),所以 151151151 是回文质数. ...

  9. P1217 [USACO1.5]回文质数 Prime Palindromes 题解(来源:洛古)

    [USACO1.5]回文质数 Prime Palindromes 题目描述 因为 151 151 151 既是一个质数又是一个回文数(从左到右和从右到左是看一样的),所以 151 151 151 是回 ...

最新文章

  1. ueditor上传图片回调_(常见解决方法)UEditor报错“后端配置项没有正常加载,上传插件不能正常使用”...
  2. 一次redis连接配置修改引发的redis.clients.jedis.exceptions.JedisConnectionException: Unexpected end of stream.异常
  3. 如何在Ubuntu中使用dpkg命令卸载软件
  4. php smtp验证,php通过smtp验证登陆
  5. 计算机关机键桌面,电脑桌面按钮关机关不了怎么办? 爱问知识人
  6. Linux查看二进制文件hexeditor
  7. FreeTextBox 3.1.6 的实践总结和几个问题
  8. lwip连续发数据卡死_LwIP用TCP连接方式在数据量比较大协议栈卡死
  9. 第一序列任小粟的能力_末世废土文—《第一序列》:“这世间,已经不需要齐天大圣了。”...
  10. sf | 读取和保存空间矢量数据
  11. C语言 后面,c语言++放在前面和后面的区别分析
  12. mysql数据库过滤数据_MySQL数据库常规操作一些简单绕过过滤的方法
  13. 可行性分析报告-学生信息管理系统
  14. Window取消快捷方式箭头(脚本方式)
  15. 京东商品主图怎么保存?如何正确的保存到原图?
  16. 聚焦手机操作系统 运营商的“门户”之战
  17. OpenCV实战——角度测量
  18. Oracle - 优化器(Optimizer)- 01概念
  19. 详解“==”和equals的区别
  20. layui分页page=true容易踩的坑

热门文章

  1. 网站设计师必备50教程
  2. 跨域问题解决方案--Nginx代理转发
  3. linux挂载与卸载(转)
  4. win7 桌面图标拖不动解决方法
  5. Spring boot处理附件的一个坑
  6. 《Spring Cloud Netflix官方文档》1.服务发现:Eureka客户端
  7. springboot com.mysql.cj.exceptions.CJException: Access denied for user 'root'@'localhost
  8. java 压缩多个文件_java实现一次性压缩多个文件到zip中的方法示例
  9. 属兔的人今日运势-360星座网_【生肖运势】12月17日
  10. solidworks钣金插件_SolidWorks钣金设计实例:等径弯管