careercup-数学与概率 7.7

7.7 有些数的素因子只有3、5、7,请设计一个算法,找出其中第k个数。

解法:

首先,我们可以将满足条件的前几个数列出来,以此寻找解题思路。

一种简单的思路就是对于已经列出的数,我们依次去乘以3,5,7得到一组数 然后找出最小且还没有列出的数,加入到这个列表。然后重复上面的步骤: 乘以3,5,7,找出最小且还没有列出的数……这个方法的时间复杂度是O(n2 )。

这种思路存在一个问题,就是重复计算。比如对于上面那个表,我想计算下一个数, 那么我用3,5,7去乘以表中的每一个数,然后找出最小且没有用过的数。 可是像3*3,3*5,3*7,5*5,5*7等等都是已经计算过且已经用了的, 按照上面的算法就会不断地重复计算。那我们有没什么办法可以避免重复计算呢? 那就是将已经计算出来的数保存好,并且保持它们有序。为了避免出现先用3乘以5, 然后又用5去乘以3的这种情况出现(这样会使我们维护的数中出现重复), 我们可以用3个队列来维护这些数。第1个队列负责乘以3,第2个队列负责乘以5, 第3个队列负责乘以7。算法描述如下:

1. 初始化结果res=1和队列q3,q5,q7
2. 分别往q3,q5,q7插入1*3,1*5,1*7
3. 求出三个队列的队头元素中最小的那个x,更新结果res=x
4. 如果x在:
    q3中,那么从q3中移除x,并向q3,q5,q7插入3*x,5*x,7*x
    q5中,那么从q5中移除x,并向q5,q7插入5*x,7*x
    q7中,那么从q7中移除x,并向q7插入7*x
5. 重复步骤3-5,直到找到第k个满足条件的数

注意,当x出现在q5中,我们没往q3中插入3*x,那是因为这个数在q5中已经插入过了。

C++实现代码:

#include<iostream>
#include<queue>
using namespace std;

int get_num(int k)
{
    if(k<=0)
        return 0;
    int res,cnt=1;
    queue<int> q3,q5,q7;
    q3.push(3);
    q5.push(5);
    q7.push(7);
    while(cnt<k)
    {
        res=min(q3.front(),min(q5.front(),q7.front()));
        if(res==q3.front())
        {
            q3.pop();
            q3.push(3*res);
            q5.push(5*res);
            q7.push(7*res);
        }
        else if(res==q5.front())
        {
            q5.pop();
            q5.push(5*res);
            q7.push(7*res);
        }
        else if(res==q7.front())
        {
            q7.pop();
            q7.push(7*res);
        }
        cnt++;
    }
    return res;
}

int main()
{
    cout<<get_num(10)<<endl;
}
时间: 2024-10-06 11:16:52

careercup-数学与概率 7.7的相关文章

POJ3682King Arthur&#39;s Birthday Celebration(数学期望||概率DP)

King Arthur is an narcissist who intends to spare no coins to celebrate his coming K-th birthday. The luxurious celebration will start on his birthday and King Arthur decides to let fate tell when to stop it. Every day he will toss a coin which has p

《统计思维程序员数学之概率统计第2版》中英文PDF+数据代码+《面向数据科学家的实用统计学》中英文PDF+源代码+学习总结

作为一个程序员,我认为,不需要把数学全部学完,要选择合适自己的资料. <统计思维:程序员数学之概率统计(第2版)>以程序模拟的方式而不是数学教材上毫无来由的定理解释了大多数统计上的基本概念.<统计思维:程序员数学之概率统计(第2版)>,中文PDF,带书签目录,204页,文字可以复制.<统计思维:程序员数学之概率统计(第2版)>,英文PDF,带书签目录,225页,文字可以复制. 配套python源代码+数据. 下载:https://pan.baidu.com/s/1Jju

数学1——概率与数学期望

1.什么是数学期望? 数学期望亦称期望.期望值等.在概率论和统计学中,一个离散型随机变量的期望值是试验中每一次可能出现的结果的概率乘以其结果的总和. 这是什么意思呢?假如我们来玩一个游戏,一共52张牌,其中有4个A.我们1元钱赌一把,如果你抽中了A,那么我给你10元钱,否则你的1元钱就输给我了.在这个游戏中,抽中的概率是$\frac{1}{13} ( \frac{4}{52} ) $,结果是赢10元钱:抽不中概率是$\frac{12}{13}$,结果是亏1元钱.那么你赢的概率,也就是期望值是$-

统计思维-程序员数学之概率统计-云图

封面 简介 本书是一本全新的概率统计入门教材,重点介绍如何用统计学方法分析大型数据集.本书会介绍如何使用计算机实现各种统计方法,这有诸多优点. 学生可以通过编写程序来深化和检查自己对概念的理解. 例如, 编写计算最小二乘拟合. 残差和判定系数的函数, 编写和测试这些代码需要他们正确理解相关概念,消除各种可能的误解. 学生能够通过计算实验来验证统计学上的一些定理. 例如, 生成服从各种分布的样本来验证中心极限定理(Central Limit Theorem,CLT). 当发现服从帕累托分布的样本并

HDU 4438 Hunters (数学,概率计算)

题意:猎人A和B要进行一场比赛.现在有两个猎物老虎和狼,打死老虎可以得X分,打死狼可以得Y分.现在有两种情况: (1)如果A与B的预定目标不同,那么他们都将猎到预定的目标. (2)如果A与B的预定目标相同,A杀死目标的概率为P,B杀死这个目标的概率为1-P.接着他们将猎取第二只猎物,概率同上. 现在A知道B选择老虎作为他的首目标的概率为Q,B选狼作为首目标的概率为1-Q.所以A必须选择他的首目标,来使得他的期望分数最高. 析:分情况讨论么,首先选Tiger,再选Wolf,看看哪个大,就选哪个,比

数学(概率):HNOI2013 游走

[题目描述] 一个无向连通图,顶点从1编号到N,边从1编号到M. 小Z在该图上进行随机游走,初始时小Z在1号顶点,每一步小Z以相等的概率随机选 择当前顶点的某条边,沿着这条边走到下一个顶点,获得等于这条边的编号的分数.当小Z 到达N号顶点时游走结束,总分为所有获得的分数之和. 现在,请你对这M条边进行编号,使得小Z获得的总分的期望值最小. [输入格式] 第一行是正整数N和M,分别表示该图的顶点数 和边数,接下来M行每行是整数u,v(1≤u,v≤N),表示顶点u与顶点v之间存在一条边. 输入保证3

机器学习中的数学系列-概率与统计

1,基本概念 (1)期望 \( E(X)=\sum_i{x_ip_i} \) ------------------- important ---------------- E(kX) = kE(X) E(X+Y) = E(X)+E(Y) 当X和Y相互独立:E(XY)=E(X)E(Y) (这个不能反向推哦) ----------------------------------------------- (2)方差 \( D(X)=\sum_i{(x_i-E(X))^2p_i} \) 从这个式子可以

9.7数学与概率(一)——给定直角坐标上的两条线,确定这两条线会不会相交

/** * 功能:给定直角坐标上的两条线,确定这两条线会不会相交. */ public class Line { static double epsilon=0.000001; public double slope;//斜率 public double yintercept;//与y轴的截距 public static void main(String[] args) { // TODO Auto-generated method stub } /** * 假设: * 1)若两条线是相同的(斜

9.7数学与概率(二)——实现整数的乘法、减法和除法运算,只允许使用加号

/** * 功能:实现整数的乘法.减法和除法运算.只允许使用加号. */ //减法 public static int minus(int a,int b){ return a+negate(b); } //取反 /** * 思路:对正数k的取反,只需要将-1连续加k次:对负数k的取反,只需要将1连续加k次. * @param a * @return */ public static int negate(int a){ int neg=0; int d=a>0?-1:1; while(a!=0

9.7数学与概率(三)——在二维平面上,有两个正方形,请找出一条直线,能够将这两个正方形对半分

/** * 功能:在二维平面上,有两个正方形,请找出一条直线,能够将这两个正方形对半分. * 假定正方形的上下两条边与x轴平行. */ /** * 考虑: * 线的准确含义,可能性有: * 1)由斜率和y轴截距确定: * 2)由这条边上的任意两点确定: * 3)线段,以正方形的边作为起点和终点. * * 假设:这条线的端点应该落在正方形的边上. * 思路:要将两个正方形对半分,这条线必须连接两个正方形的中心点. */ public class Square { //正方形的四条边 int lef