section 1.5 sprime

5 篇文章 0 订阅
4 篇文章 0 订阅
这篇博客介绍了C++在section 1.5 sprime问题上的解决方法,内容与section 1.5 pprime相似。文章重点讨论了针对质数验证的两种情况,即当数值小于等于10000和大于等于10000时的不同处理策略。
摘要由CSDN通过智能技术生成

-这道题和section 1.5 pprime思路几乎一模一样
-质数验证函数分了两类,num<=10000和num>=10000

"YOUR PROGRAM ('sprime') WORKED FIRST TIME!  That's fantastic and a rare thing.  Please accept these special automated
congratulations."
/*
ID: penglin3
PROG: sprime
LANG: C++11
*/
#include <iostream>
#include <fstream>
#include <vector>
#include <math.h>
using namespace std;//fstream 需要std合法范围

bool bPrime[10001]{};
vector<int> viPrime{};
vector<long> answer{};

#define min(a , b) ((a < b) ? a : b)
//建质数表的函数,然后写入bPrime,vbPrime
void listPrime(bool *bPrime,vector<int> &viPrime, const int& maxnum);
//判断是否为素数
bool judgePrime(const bool *bPrime,const vector<int>&viPrime, const long& num);
//生成Superprime n当前位数,N总位数,sp是生成的数
void Superprime(const int& n, const int& N,const long sp, void f(long sp));
//处理superprime的函数;
void f(long sp);
int main() {
    ifstream fin("sprime.in");
    ofstream fout("sprime.out");

    int N;
    fin >> N;

    //处理
    listPrime(bPrime, viPrime, pow(10, min(4, N)));
    Superprime(1, N, 0, f);

    //输出
    for (auto &itan : answer)
        fout << itan << endl;

    fin.close();
    fout.close();
    return 0;
}

//建质数表的函数,数n:3,5,7...maxnum数组最大下标,然后写入vbPrime
void listPrime(bool *bPrime,vector<int> &viPrime, const int& maxnum) {
    bPrime[0] = true;
    bPrime[1] = true;

    for (int i = 4; i <= maxnum; i += 2 ) {
        bPrime[i] = true;
    }
    int n = 3;

    while (n * n < maxnum) {
        for (int i = n * n; i <= maxnum; i += n) {
                bPrime[i] = true;
            }
        do//这里必须用do-while
            n += 2;
        while (n * n < maxnum && bPrime[n]);
    }

    for (int i = 2; i <= maxnum; ++i)
        if (i % 2 && !bPrime[i]) viPrime.push_back(i);

    return;
}
/*---------------------------------------------------------*/
//判断是否为素数
bool judgePrime(const bool *bPrime,const vector<int>&viPrime, const long& num) {
    if (num <= 10000) {
        return !(bPrime[num]);
    }
    else {
        for (int i = 0; i != viPrime.size(); ++i) {
            if (viPrime[i] > sqrt(num)) break;
            else if (!(num % viPrime[i]))return false;
        }
        return true;
    }
}
/*---------------------------------------------------------*/
//生成Superprime n当前位数,N总位数,sp是生成的数
void Superprime(const int& n,const int& N, const long sp, void f(long sp)) {
    if (n == 1) {
        int i = 2;
        Superprime(n + 1, N, i, f);
        for (i = 3; i <= 7; i += 2) {
            Superprime(n + 1, N, i, f);
        }
    }

    else if (n <= N) {
        long sp2 = 0;
        for (int i = 1; i <= 9; i += 2) {
            sp2 = i + sp*10;
            if (judgePrime(bPrime, viPrime, sp2)) Superprime(n + 1, N, sp2, f);
        }
    }
    else {
        f(sp);
    }
    return;
}
//处理superprime的函数;
void f(long sp) {
    answer.push_back(sp);
}
动态规划(Dynamic Programming,DP)是一种高效的算法思想,可以用来求解一类具有最优子结构性质的问题。在Matlab中,可以使用dpopt函数来求解动态规划问题。下面是一个简单的背包问题的Matlab代码实现。 假设有一个背包,最多能装重量为W的物品。有n个物品,每个物品有一个重量wi和一个价值vi。我们要在不超过背包容量的前提下,使得所装物品的总价值最大。 首先,我们定义一个结构体,表示每个物品的重量和价值: ```matlab items = struct('w', [2 1 3 2], 'v', [12 10 20 15]); ``` 然后,我们定义一个函数dpfun,用于计算背包问题的最优解。该函数接受一个状态s和一个决策d作为输入,返回下一个状态s'和决策的价值v。状态s表示前i个物品已经被考虑过,且已经装了总重量为w的物品,决策d表示是否将第i个物品装入背包。 ```matlab function [sprime, v] = dpfun(s, d) i = s(1); % 前i个物品已经被考虑过 w = s(2); % 已经装了总重量为w的物品 if i == length(items) % 已经考虑完所有物品 sprime = []; % 下一个状态为空 v = 0; % 决策价值为0 elseif w + d * items(i+1).w > W % 装入第i+1个物品会超重 [sprime, v] = dpfun([i+1 w], 0); % 不装入第i+1个物品 else % 装入第i+1个物品不会超重 [sprime1, v1] = dpfun([i+1 w], 0); % 不装入第i+1个物品 [sprime2, v2] = dpfun([i+1 w+items(i+1).w], 1); % 装入第i+1个物品 v2 = v2 + items(i+1).v; % 决策价值加上第i+1个物品的价值 if v1 >= v2 % 不装入第i+1个物品更优 sprime = sprime1; v = v1; else % 装入第i+1个物品更优 sprime = sprime2; v = v2; end end end ``` 最后,我们调用dpopt函数求解背包问题的最优解,代码如下: ```matlab W = 5; % 背包容量 s0 = [0 0]; % 初始状态:前0个物品已经被考虑过,未装入任何物品 dp = dpopt(@dpfun, s0); % 求解最优解 v = dp.finalvalue % 最优解的价值 x = dp.finalstate(:,2) % 最优解的决策 ``` 运行结果为: ```matlab v = 37 x = 0 1 1 0 ``` 表示最优解的总价值为37,将第2个和第3个物品装入背包,其余物品不装入。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值