希望能够解释解释其中的思路,难点,以及解决方案等,稍微详细一点,谢谢
#include<stdio.h>
#include<stdbool.h>
// 思路:从1开始遍历每个数,判断是不是H数,直到得到的H数个数等于N
// 如果一个数的质因子只有2、3、5、7
// 那不断地除以2、3、5、7后,结果必然为1
bool isHNumber(int number)
{
if (number == 1)return false;
while (number % 2 == 0)number /= 2;
while (number % 3 == 0)number /= 3;
while (number % 5 == 0)number /= 5;
while (number % 7 == 0)number /= 7;
return number == 1;
}
int main()
{
// 输入N
int N;
if (scanf("%d", &N) != 1)
{
// 错误的输入直接返回
return 0;
}
// 检查N,不能小于0,也不能大于300
if (N < 0)N = 0;
if (N > 300)N = 300;
int cnt = 0, testNum = 1;
int result[300];
// 从1开始测试每个数是不是H数
while (cnt < N)
{
//如果是H数,就把它放到数组
if (isHNumber(testNum))
{
result[cnt++] = testNum;
}
++testNum;
}
// 输出到文件
FILE* file = fopen("result.txt", "w");
for (int i = 0; i < cnt; ++i)
{
fprintf(file, "%d", result[i]);
// 最后一个数后面是\n,其他数后面是、
if (i != cnt - 1)fprintf(file, "、");
else fprintf(file, "\n");
}
fclose(file);
return 0;
}
加上文件存入就行了
#include<stdio.h>
int main()
{
int n;
scanf("%d",&n);
int num=2,count=0;
while(n)
{
if(num%2==0||num%3==0||num%5==0||num%7==0)
{
printf("%d ",num);
count++;
}
num++;
if(count==n)
break;
}
return 0;
}
// 大概想法是先找出包含因子2,3,5,7数,在从这些数中找出因子不是2,3,5,7的数忽略掉并进行下一个数。
// 保存文件部分自己添加上
#include<stdio.h>
int main()
{
int N,num=2,i;
int OK;
scanf("%d",&N);
while(N>0)
{
OK=0;
if(num%2==0 || num%3==0 || num%5==0 || num%7==0)//筛选包含因子2,3,5,7的数
{
OK=1;
for(i=2;i<num;i++)
{
if(num%i==0)//筛选其他因子
{
if(!(i%2==0 || i%3==0 || i%5==0 || i%7==0)) //筛选其他因子的因子不是2,3,5,7的数
{
OK=0;
break;
}
}
}
}
if(OK)
{
printf("%d ", num);
N--;
}
num++;
}
system("pause");
return 0;
}
供参考:
#include<stdio.h>
#define min(a,b) (a)>(b)?(b):(a)
void UglyNumber(int n)
{
FILE* fp;
int* m = new int[n + 1];
m[0] = 1;
int i, a = 0, b = 0, c = 0, d = 0;
for (i = 1; i <= n; i++) {
m[i] = min(min(min(m[a] * 2, m[b] * 3), m[c] * 5), m[d] * 7);
if (m[i] == m[a] * 2)
a++;
if (m[i] == m[b] * 3)
b++;
if (m[i] == m[c] * 5)
c++;
if (m[i] == m[d] * 7)
d++;
}
for (i = 1; i <= n; i++)//输出一行 10 个
printf(i % 10 == 0 ? "%5d\n" : "%5d", m[i]);
if ((i - 1) % 10 != 0)
printf("\n");
fp = fopen("uglynumber.txt", "w");//保存到文件
if (fp == NULL) {
printf("Save to file fail!\n");
}
else {
for (i = 1; i <= n; i++)
fprintf(fp, "%5d", m[i]);
fclose(fp);
}
delete[]m;
}
int main()
{
int n;
while (scanf("%d", &n) == 1 && n >= 1 && n <= 300)//多组输入,输入n 大于300 或 小于1 时退出运行。
UglyNumber(n);
return 0;
}
就 2~10 是H数吗,往后都不是,这样理解对不
可以参考这篇文章,思路类似。
https://blog.csdn.net/Fly_as_tadpole/article/details/82705774
//首先实现一个求最小值的函数,在后面会用得到
int GetMin(int a,int b,int c)
{
if(a <= b && a <= c)
return a;
else if(b <= c && b <= a)
return b;
else
return c;
}
int GetUglyNumber_Solution(int index )
{
int arr[index];
if(index < 7)//小于7的丑数直接返回自身就可以
return index;
else//这是大于7时的方案
{
arr[0] = 1;//首先把数组第一个元素初始化为1,作为万物之伊始
int temp2 = 0,temp3 = 0,temp5 = 0,j = 0,p2,p3,p5;
/*temp2、temp3、temp5代表了三个乘积的指针,p2、p3和p5则记录了
当前其对应的指针指向的值与自身倍数的乘积。j用来判断是否到达了要
求丑数的范围。*/
while(j < index)
{
if(arr[temp2]*2 > arr[j])
p2 = arr[temp2]*2;
/*如果当前的乘积大于最右端丑数,指针无需移动,只需记录下
这个乘积*/
else
p2 = arr[++temp2]*2;
//这个与上一语句的差别仅在于是否移动指针
//下面均同理
if(arr[temp3]*3 > arr[j])
p3 = arr[temp3]*3;
else
p3 = arr[++temp3]*3;
if(arr[temp5]*5 > arr[j])
p5 = arr[temp5] * 5;
else
p5 = arr[++temp5] * 5;
arr[++j] = GetMin(p2,p3,p5);
/*最后比较一下三个乘积的最小值,别忘了要++j把他加在当前数组
末尾的下一位*/
}
}
return arr[index-1];
}
int main()
{
int k = 0;
scanf("%d", &k);
printf("%d", GetUglyNumber_Solution(k));
}