日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

USACO Section 1.5 Prime Palindromes 解题报告

發(fā)布時間:2025/3/21 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 USACO Section 1.5 Prime Palindromes 解题报告 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

題目

題目描述

題目就是給定一個區(qū)間[a,b]((5 <= a < b <= 100,000,000)),我們需要找到這個區(qū)間內(nèi)所有既是回文串又是素數(shù)的數(shù)字。

輸入樣例

5 500

輸出樣例

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

解題思路

因為數(shù)據(jù)范圍特別大,如果我們直接枚舉所有的素數(shù)然后再判斷是不是回文串的話肯定會超時。在題目的下面有hints,其中就告訴我們要逆向思維,既然我們枚舉素數(shù)太多了,那么我們就可以先枚舉出所有可能的回文串(這個數(shù)量比較少),然后再判斷回文串是不是素數(shù)。下面就直接模擬這個過程就好了,在寫代碼的時候,主要是枚舉回文串比較費勁,要細(xì)心一點。

解題代碼

/* 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;// 先轉(zhuǎn)化為int型整數(shù),然后再判斷是否是素數(shù)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() {// 保證要我們要求的區(qū)間內(nèi)// 如果回文串的長度位于alen與blen之間,那么就代表已經(jīng)是位于區(qū)間內(nèi)了if (len == alen && strcmp(str, astr) < 0) return ;if (len == blen && strcmp(str, bstr) > 0) return ;if (isPrime()) {cout << str << endl;} }// cur用來記錄現(xiàn)在產(chǎn)生的是回文串的第幾位 void makePalindromes(int cur) {if (cur == len/2) {if (len%2 == 0) { // 產(chǎn)生偶數(shù)長度的str[len] = '\0';judge();} else { // 產(chǎn)生奇數(shù)長度的回文串,中間的那個位置可以為任意數(shù)字for (int i = 0; i <= 9; ++i) {str[cur] = i+'0';str[len] = '\0';judge();}}return ;}if (cur == 0) { // 在規(guī)定了長度的情況下,首位不能為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); }

轉(zhuǎn)載于:https://www.cnblogs.com/yinzm/p/7430038.html

總結(jié)

以上是生活随笔為你收集整理的USACO Section 1.5 Prime Palindromes 解题报告的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。