UVA897 Anagrammatic Primes【筛选法+离线程序+代码生成+条件编译】

A number greater than one is prime if it has no divisors other than itself and 1 (note that 1 is not prime). For example, 23 is prime and 35 is not prime because 35 = 7 × 5. When the digits of a number are rearranged, its primeness may change — for example, 35 is not prime but 53 is. For this problem, you have to find numbers which are prime no matter how you rearrange their digits. For example, all of the numbers 113, 131 and 311 are prime, so we say that 113 is an anagrammatic prime (also 131 and 311 are anagrammatic primes).
Input
Each line of input will contain a single positive number n, less than 10,000,000. You must find the first anagrammatic prime which is larger than n and less than the next power of 10 greater than n. The input will be terminated by a line consisting of a single ‘0’.
Output
For each number in the input, one line of output must be produced. This output line should contain either the next anagrammatic prime, as described above, or ‘0’ if there is no anagrammatic prime in the range defined.
Sample Input
10
16
900
113
8000000
0
Sample Output
11
17
919
131
0

问题链接UVA897 Anagrammatic Primes
问题简述:计算比n大并且字母重排字迷问题的素数,即本身和重排后都是素数的数字。
问题分析:用离线打表法生成代码的方法来解决。
程序说明:采用条件编译,把离线代码和在线代码写在一起了。
参考链接:(略)
题记:(略)

AC的C++语言程序如下:

/* UVA897 Anagrammatic Primes */

#include <bits/stdc++.h>

//#define NOONLINE

using namespace std;

#ifdef NOONLINE
int biger(int n)
{
    int digits[10];
    memset(digits, 0, sizeof(digits));
    while(n) {
        digits[n % 10]++;
        n /= 10;
    }

    int ans = 0;
    for(int i = 9; i >= 0; i--) {
        while(digits[i]) {
            ans = ans * 10 + i;
            digits[i]--;
        }
    }
    return ans;
}

const int N = 10000000;
const int SQRTN = sqrt((double) N);
bool isprime[N + 1];
// Eratosthenes筛选法
void esieve(void)
{
    memset(isprime, true, sizeof(isprime));

    isprime[0] = isprime[1] = false;
    for(int i = 2; i <= SQRTN; i++) {
        if(isprime[i]) {
            for(int j = i * i; j <= N; j += i)  //筛选
                isprime[j] = false;
        }
    }

    int a;
    for(int i = 2; i <= N; i++)
        if(!isprime[i] && isprime[a = biger(i)])
            isprime[a] = false;
    for(int i = 2; i <= N; i++)
        if(isprime[i] && !isprime[biger(i)])
            isprime[i] = false;

    int cnt = 0;
    for(int i = 2; i <= N; i++)
        if (isprime[i]) cnt++;

    printf("const int N = %d;\n", cnt);
    printf("const int prime[%d] = {", cnt);
    for(int i = 2; i <= N; i++)
        if (isprime[i])
            printf("%d, ", i);
    printf("};\n");
}

int main()
{
    esieve();

    return 0;
}

#endif

#ifndef NOONLINE

const int N = 22;
const int prime[22] = {2, 3, 5, 7, 11, 13, 17, 31, 37, 71, 73, 79, 97, 113, 131, 199, 311, 337, 373, 733, 919, 991, };

int main()
{
    int n;
    while (~scanf("%d", &n) && n) {
        int u = 1, tmp = n, flag = 1;
        while (tmp) {
            u *= 10;
            tmp /= 10;
        }
        for (int i = 0; i < N; i++)
            if (prime[i] > n && prime[i] < u) {
                printf("%d\n", prime[i]);
                flag = 0;
                break;
            }
        if (flag) printf("0\n");
    }

    return 0;
}
#endif
发布了2126 篇原创文章 · 获赞 2306 · 访问量 254万+

猜你喜欢

转载自blog.csdn.net/tigerisland45/article/details/104586928