Project Euler 51: Prime digit replacements

题目描述:

By replacing the 1st digit of the 2-digit number *3, it turns out that six of the nine possible values: 13, 23, 43, 53, 73, and 83, are all prime.

By replacing the 3rd and 4th digits of 56**3 with the same digit, this 5-digit number is the first example having seven primes among the ten generated numbers, yielding the family: 56003, 56113, 56333, 56443, 56663, 56773, and 56993. Consequently 56003, being the first member of this family, is the smallest prime with this property.

Find the smallest prime which, by replacing part of the number (not necessarily adjacent digits) with the same digit, is part of an eight prime value family.

 

我是采用最暴力的方法来做的,由于跑出来的结果小于1S,所以我也没怎么去优化。其实是存在很多优化条件的,读者可以自行思考。

 

#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <cassert>
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
#include <deque>
#include <list>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <utility>
#include <numeric>
#include <algorithm>
#include <functional>
using namespace std;

typedef long long ll;
const int inf = 0x3f3f3f3f;
const ll  INF = 0x3f3f3f3f3f3f3f3fLL;
const double eps = 1e-8;
const double pi  = acos(-1.0);
const int maxn = 1000010;
bool is_prime[maxn];
int  prime[maxn];
int  len;

void init() {
    int i, j; len = 0;
    memset(is_prime, true, sizeof(is_prime));
    prime[len++] = 2;
    for(i = 4; i < maxn; i += 2) {
        is_prime[i] = false;
    }
    for(i = 3; i * i <= maxn; i += 2) {
        if(is_prime[i]) {
            prime[len++] = i;
            for(j = i * i; j < maxn; j += i) {
                is_prime[j] = false;
            }
        }
    }
    for( ; i < maxn; i += 2) {
        if(is_prime[i]) {
            prime[len++] = i;
        }
    }
    return ;
}

int get_cnt(int x) {
    if(x == 0) return 1;
    int cnt = 0;
    while(x) cnt++, x /= 10;
    return cnt;
}

bool check(int x) {
    int m = (int)floor(sqrt(x * 1.0) + 0.5);
    for(int i = 2; i <= m; ++i) {
        if(x % i == 0) return false;
    }
    return true;
}

void solve() {

    //int arr[10];
    int a[10], b[10];
    bool flag = false;
    for(int i = 0; ; ++i) {
        int t_len = get_cnt(prime[i]);
        for(int j = 1; j < (1<<t_len); ++j) {
            int ans = inf;
            for(int t = j, k = 0, tt = i; k < t_len; ++k, t >>= 1, tt /= 10) {
                a[k] = t & 1; b[k] = tt % 10;
            }
            int t = -1;
            bool ok = true;
            for(int k = 0; k < t_len; ++k) {
                if(a[k] & 1) {
                    if(t == -1) t = b[k];
                    else if(t != b[k]) {
                        ok = false;
                        break;
                    }
                }
            }
            if(!ok) continue;
            int cnt = 0;
            if(a[t_len-1] == 1) {
                for(int k = 1; k <= 9; ++k) {
                    int ttt = 0;
                    for(int l = t_len-1; l >= 0; --l) {
                        if(a[l] & 1) {
                            ttt = ttt * 10 + k;
                        } else {
                            ttt = ttt * 10 + b[l];
                        }
                    }
                    if(is_prime[ttt]) {
                        cnt++;
                        //arr[cnt++] = ttt;
                        ans = min(ans, ttt);
                    }
                }
            } else {
                for(int k = 0; k <= 9; ++k) {
                    int ttt = 0;
                    for(int l = t_len-1; l >= 0; --l) {
                        if(a[l] & 1) {
                            ttt = ttt * 10 + k;
                        } else {
                            ttt = ttt * 10 + b[l];
                        }
                    }
                    if(is_prime[ttt]) {
                        cnt++;
                        //arr[cnt++] = ttt;
                        ans = min(ans, ttt);
                    }
                }
            }
            if(cnt == 8) {
                printf("%d\n", ans);
                /*
                for(int x = 0; x < 8; ++x) {
                    printf("%d ", arr[x]);
                }
                printf("\n");
                */
                flag = true;
                break;
            }
        }
        if(flag) break;
    }
    return ;
}

int main() {

    init();
    solve();
    return 0;
}

 

posted on 2015-01-27 17:43  sponge_wxy  阅读(113)  评论(0)    收藏  举报

导航