USACO Section 1.5 Superprime Rib 解题报告

题目

题目描述

超级素数的定义如下:如果有个素数我们从右往左依次去掉一位数,每次去掉一位数剩下的数仍然是素数,那么我们称这个数是超级素数。例如7331,这是一个素数,从右往左依次去掉一位数733, 73, 7,这些数字仍然是素数,所以7331是一个超级素数。
输入一个数字n (1<=n<=8),代表要找的超级素数的长度。现在需要按照从小到大排序的所有长度为n的超级素数。

样例输入

4

样例输出

2333
2339
2393
2399
2939
3119
3137
3733
3739
3793
3797
5939
7193
7331
7333
7393

解题思路

因为数据量不大所以我们直接搜索出所有的长度为n的数,然后判断是否是超级素数。在搜索时,我们可以从左往右开始枚举,每次产生一个数,我们就立刻进行素数判断。如果不是素数,那么就没必要接着枚举了,这是一个剪枝的方法。例如我们需要产生一个4位数,我现在已经产生了前两位21,判断21不是素数,所以没必要接着往下枚举了。

解题代码

/*
ID: yinzong2
PROG: sprime
LANG: C++11
*/
#define MARK
#include <iostream>
#include <cstdlib>
using namespace std;

int n;
char buf[10];

bool isPrime() {
    int val = atoi(buf);
    if (1 == val) return false;
    if (2 == val) return true;
    if (0 == (val%2)) return false;
    for (int i = 3; i*i <= val; i += 2) {
        if (0 == (val%i)) {
            return false;
        }
    }
    return true;
}

void produceSPrime(int idx) {
    if (idx == n) {
        cout << buf << endl;
        return ;
    }
    int i = 0;
    if (idx == 0) i++;
    for (; i <= 9; ++i) {
        char c = i+'0';
        buf[idx] = c;
        buf[idx+1] = '\0';
        if (isPrime()) { // 剪枝
            produceSPrime(idx+1);
        }
    }
}

int main() {
#ifdef MARK
    freopen("sprime.in", "r", stdin);
    freopen("sprime.out", "w", stdout);
#endif // MARK
    while (cin >> n) {
        produceSPrime(0);
    }
    return 0;
}

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值