USACO Section 1.5 Prime Palindromes 解题报告
生活随笔
收集整理的這篇文章主要介紹了
USACO Section 1.5 Prime Palindromes 解题报告
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目
題目描述
題目就是給定一個區間[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 解题报告的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 超市账单管理------之获取总记录数
- 下一篇: 达人篇:2.1)零缺陷管理法;