c语言寻找丑数,C语言程序设计100例之(14):丑数
例14 丑数
问题描述
丑数是其质因子只可能是2,3或5的数。前10个丑数分别为1, 2, 3, 4, 5, 6, 8, 9, 10, 12。输入一个正整数n,求第n个丑数。
输入格式
每行为一个正整数n (n <= 1500),输入n=0结束。
输出格式
每行输出一个整数,表示求得的第n个丑数。
输入样例
1
2
50
0
输出样例
1
2
243
(1)编程思路。
根据丑数的定义,丑数从小到大排列的序列中的一个数应该是其前面某个数乘以2、3或者5的结果。因此,可以定义一个数组num[1501]来顺序保存序列中的丑数,数组里面的每一个元素的值是前面的某个元素值乘以2、3或者5得到。
问题的关键是怎样确保数组里面的各元素是按值的大小依次生成的。
假设数组中已经有若干个序列中的元素,排好序后存在数组中。把序列中现有的最大的数记做M。由于序列中的下一个数肯定是前面某一个数乘以2、3或者5的结果。首先考虑把已有的每个数乘以2。在乘以2的时候,能得到若干个结果小于或等于M的。由于数组中的元素是按照顺序生成的,小于或者等于M的数肯定已经在数组中了,不需再次考虑;还会得到若干个大于M的结果,但只需要第一个大于M的结果,因为数组中的元素是按值从小到大顺序生成的,其他更大的结果可以以后再说,记下得到的第一个乘以2后大于M的数M2。同样,把已有的每一个数乘以3和5,记下得到的第一个大于M的结果M3和M5。那么,序列中下一个数应该是M2、M3和M5三个数的最小者。
事实上,上面所说的把数组中已有的每个数分别都乘以2、3和5,是不需要的,因为已有的数是按顺序存在数组中的。对乘以2而言,肯定存在某一个数T2,排在它之前的每一个数乘以2得到的结果都会小于已有最大的数,在它之后的每一个数乘以2得到的结果都会太大。因此,只需要记下这个数的位置P2,同时每次生成一个新的序列中的数的时候,去更新这个P2。对乘以3和5而言,存在着同样的P3和P5。
定义变量index保存当前待生成的数在序列中的序号,显然,已生成的序列中的最大元素为Num[curIndex-1]。
定义3个指针变量int *p2,*p3,*p5;分别指向数组中的3个元素,排在所指元素之前的每一个数乘以2(或3、或5)得到的结果都会小于已有最大的数num[index-1],在所指元素之后的每一个数乘以2(或3、或5)得到的结果都会太大。
初始时,num[1] = 1、index =2、p2 = p3 = p5 = &num[1]。
生成第index个元素的方法为:
if (*p2 * 2
else min= *p3 * 3;
if (min> *p5 * 5) min=*p5 * 5;
num[index] = min;
第index个元素生成后,需要对指针p2、p3和p5进行更新,更新方法为:
if(num[index]==*p2*2) p2++;
if(num[index]==*p3*3) p3++;
if(num[index]==*p5*5) p5++;
(2)源程序。
#include
#include
int main()
{
int num[1501],index,min,n;
int *p2,*p3,*p5;
p2=p3=p5=&num[1];
num[1]=1;
for (index=2;index<=1500;index++)
{
if (*p2 * 2
else min= *p3 * 3;
if (min> *p5 * 5) min=*p5 * 5;
num[index] = min;
if(num[index]==*p2*2) p2++;
if(num[index]==*p3*3) p3++;
if(num[index]==*p5*5) p5++;
}
while(scanf("%d",&n) && n!=0)
{
printf("%d
",num[n]);
}
return 0;
}
习题14
14-1 Hamming Problem
本题选自北大POJ 题库 (http://poj.org/problem?id=2545)
Description
For each three prime numbers p1, p2 and p3, let's define Hamming sequence Hi(p1, p2, p3), i=1, ... as containing in increasing order all the natural numbers whose only prime divisors are p1, p2 or p3.
For example, H(2, 3, 5) = 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 16, 18, 20, 24, 25, 27, ...
So H5(2, 3, 5)=6.
Input
In the single line of input file there are space-separated integers p1 p2 p3 i.
Output
The output file must contain the single integer - Hi(p1, p2, p3). All numbers in input and output are less than 10^18.
Sample Input
7 13 19 100
Sample Output
26590291
(1)编程思路。
弄明白了例14的编程思想,本题就简单了,无非是将例14中的质数2,3、5参数化为p1、p2和p3而已。
(2)源程序。
#include
int main()
{
long long p1,p2,p3,H[100005];
int n,i,a1,a2,a3;
while(scanf("%lld%lld%lld%d",&p1,&p2,&p3,&n)!=EOF)
{
H[0] = 1;
a1=a2=a3=0;
for (i = 1;i<=n;i++)
{
H[i] = p1*H[a1]if (H[i]>p3*H[a3]) H[i]=p3*H[a3];
if(H[i]==p1*H[a1]) a1++;
if(H[i]==p2*H[a2]) a2++;
if(H[i]==p3*H[a3]) a3++;
}
printf("%lld
",H[n]);
}
return 0;
}
14-2 丑数 Humble Numbers
本题选自洛谷题库 (https://www.luogu.org/problem/ P2723)
题目描述
对于一给定的素数集合 S = {p1, p2, ..., pK},考虑一个正整数集合,该集合中任一元素的质因数全部属于S。这个正整数集合包括,p1、p1*p2、p1*p1、p1*p2*p3...(还有其它)。该集合被称为S集合的“丑数集合”。注意:我们认为1不是一个丑数。
将丑数集合中每个数从小到大排列,每个丑数都是素数集合中的数的乘积,第N个“丑数”就是在能由素数集合中的数相乘得来的(包括它本身)第n小的数。
你的工作是对于输入的集合S去寻找“丑数集合”中的第N个“丑数”。
输入格式
第 1 行: 二个被空格分开的整数:K 和 N,1<= K<=100 ,1<= N<=100,000。
第 2 行: K 个被空格分开的整数:集合S的元素。
输出格式
单独的一行,输出对于输入的S的第N个丑数。所有输出答案可以用longint(32位整数)存储。
输入样例
4 19
2 3 5 7
输出样例
27
(1)编程思路。
本题在习题14-1的基础上更进一步,可以指定多个质数,这些质数来自集合S。因此在习题14-1的基础上,用数组p[101]来代替p1、p2和p3,采用循环处理即可。具体参见源程序。
(2)源程序。
#include
int main()
{
int p[101],a[101],H[100005];
int k,n,i,j;
scanf("%d%d",&k,&n);
H[0] = 1;
for (i=1;i<=k;i++)
{
scanf("%d",&p[i]);
a[i]=0;
}
for (i = 1;i<=n;i++)
{
H[i] = p[1]*H[a[1]];
for (j=2;j<=k;j++)
if (H[i]>p[j]*H[a[j]]) H[i]=p[j]*H[a[j]];
for (j=1;j<=k;j++)
if(H[i]==p[j]*H[a[j]]) a[j]++;
}
printf("%d
",H[n]);
return 0;
}
14-3 集合S
问题描述
一个集合S有如下元素:1是集合S的元素;若x是集合S的元素,则2x+1,3x+1也是集合S的元素。将集合S的元素按从小到大排列后,问第N个元素是多少?
输入格式
输入包含多个数据,每个数据为一个正整数N (1 <= N <= 10000000)。.
输出格式
对每个N,在单独一行输出集合S中第N个元素。
输入样例
100
254
输出样例
418
1461
(1)编程思路。
这道习题和例14的解题思路是完全一样的。两个指针p2和p3从0开始起头并进,一个表示 x2+1,另一个表示x3+1,哪个小前进哪个,如果两个相等就都前进。这样就可以产生出递增的不重复的序列。
定义数组int num[10000001]保存产生的这个序列的前10000000项,这样输入n后,直接输出数组元素num[n]即可。
(2)源程序。
#include
int num[10000001];
int main()
{
int p2,p3,i,min,n;
num[1]=1;
p2=p3=1;
i=1;
while(i<10000000)
{
min=2*num[p2]+1;
if (min>3*num[p3]+1) min=3*num[p3]+1;
num[++i]=min;
if(num[i]==2*num[p2]+1) p2++;
if(num[i]==3*num[p3]+1) p3++;
}
while (scanf("%d",&n)!=EOF)
{
printf("%d
",num[n]);
}
return 0;
}
c语言寻找丑数,C语言程序设计100例之(14):丑数相关推荐
- c语言经典程序表白6,经典C语言程序设计100例(6)
[程序61] 题目:打印出杨辉三角形(要求打印出10行如下图) 1.程序分析: 1 1 1 1 2 1 1 3 3 1 1 4 6 4 1 1 5 10 10 5 1 2.程序源代码: main() ...
- Go语言开发小技巧易错点100例(七)
往期回顾: Go语言开发小技巧&易错点100例(一) Go语言开发小技巧&易错点100例(二) Go语言开发小技巧&易错点100例(三) Go语言开发小技巧&易错点10 ...
- c语言编程 生理周期的程序,C语言程序设计100例之(9):生理周期
例9 生理周期 问题描述 人生来就有三个生理周期,分别为体力.感情和智力周期,它们的周期长度为 23 天.28 天和33 天.每一个周期中有一天是高峰.在高峰这天,人会在相应的方面表现出色.例如 ...
- 简单c语言程序求和,C语言程序设计100例之(23):数列求和
例23 数列求和 问题描述 已知某数列前两项为2和3,其后继项根据前面最后两项的乘积,按下列规则生成: ① 若乘积为一位数,则该乘积即为数列的后继项: ② 若乘积为二位数,则该乘积的十位上的数字和个 ...
- c语言黑匡程序,2020年新版C语言实用程序设计100例流程图.docx
C 语言实用程序 100 例 第一篇 基础与提高 实例 1 利用库函数编写基本显示程序 实例 2 变量属性 实例 3 运算符与类型 实例 4 关于程序结构 实例 5 显示函数曲线图 实例 6 二分法选 ...
- c语言程序设计拉丁方阵结构图,C语言程序设计100例之(29):拉丁方阵
例29 拉丁方阵 问题描述 构造 NXN 阶的拉丁方阵,使方阵中的每一行和每一列中数字1到N只出现一次.如N=4时: 1 2 3 4 2 3 4 1 3 4 1 2 4 1 2 3 输入格式 一个正 ...
- c语言15除以2得到8,C语言程序设计100例之(15):除法算式
例15 除法算式 问题描述 输入正整数n(2≤n≤68),按从小到大输出所有形如abcde/fghi=n的表达式.其中a~i为1~9的一个排列. 输入格式 每行为一个正整数n (n <= 1 ...
- c语言连发程序,C语言程序设计100例之(3): Cantor表
例3 Cantor表 题目描述 现代数学的著名证明之一是Georg Cantor证明了有理数是可枚举的.他是用下面这一张表来证明这一命题的: 1/1 1/2 1/3 1/4 -- 2/1 ...
- 寻找最大公约数c语言,C语言程序设计100例之(10):最大公约数
例10 最大公约数 问题描述 有三个正整数a,b,c(0 输入数据 第一行输入一个n,表示有n组测试数据,接下来的n行,每行输入两个正整数a,b. 输出格式 输出对应的c,每组测试数据占 ...
- 随机数插入排序c 语言,C语言程序设计100例之(22):插入排序
例22 插入排序 问题描述php 排序是计算机程序设计中的一种重要操做,它的功能是将一个数据元素或记录的任意序列,从新排列成一个以关键字递增(或递减)排列的有序序列.算法 排序的方法有不少,简单插入 ...
最新文章
- 70.nodejs操作mongodb
- 锁存器和触发器的区别
- 最好用的 IntelliJ 插件 Top 10
- ubuntu上玩3D,把状态栏面板栏给玩没了
- VC++的dll中接收消息
- 计算机安装最新的安全补丁,Win10不要装!微软发布4月安全补丁合集
- 非常实用的安卓第三方库
- 如何搞定知乎模拟登陆的加密难题?
- 第三篇 层次类非线性表的编程实验 第9章 应用二叉树的基本概念编程
- android studio如何重启,从Android Studio重新启动ADB(Restart ADB from Android Studio)
- 关于高通平台9008线刷的一些注意点,供小白食用。
- Switchport详细用法
- Oracle多个数据库备份和还原,oracle 多数据库还原
- Codeforces 148D. Bag of mice(概率dp)
- Android 给RecyclerView添加头部和尾部
- 一篇文章构建你的 NodeJS 知识体系
- 安卓测试基础入门——ADB命令
- bzoj2757【scoi2012】Blinker的仰慕者
- 【实战】物联网安防监控项目【4】———从网页上控制A9的LED灯
- 两台win 7系统电脑 一台双网卡 共享上网