C:(一开始自己写的,40分)
#include <stdio.h>
int main()
{
int n, biao = 1;
int a[10001];
scanf("%d", &n);
int j = 0,k = 0;
for (int i = 2; i <= n - 1, k <= n; i++)
{
if (((i % 2 != 0) && (i % 3 != 0) && (i % 5 != 0) && (i % 7 != 0)) || i == 2 ||i == 3 || i == 5 || i == 7)
{
if ((k += i) > n)
{
break;
}
a[++j] = i;
printf("%d\n", i);
}
}
printf("%d", j);
return 0;
}
C:(研究过相关知识改良后,100分)
#include <stdio.h>
int n;
bool shai(int a)
{
for (int i = 2; i * i <= a; i++)
{
if (a % i == 0)
{
return 0;
}
}
return 1;
}
int main()
{
int a[10001];
scanf("%d", &n);
int j = 0,k = 0;
for (int i = 2; i <= n - 1, k <= n; i++)
{
if (shai(i))
{
if ((k += i) > n)
{
break;
}
a[++j] = i;
printf("%d\n", i);
}
}
printf("%d", j);
return 0;
}
C++:(100分)(学习欧拉筛后用欧拉筛法)
#include <stdio.h>
#define Max 100010 //这个最好大一些,不然我试过如果是10001的话可能会RE
bool num[Max] = { 0 }; //创建一个 有Max个元素 每个元素为bool类型 每一个元素默认为0 的数组
//创建这个数组的目的:
//通过下标间接遍历所有数( 下标=0是不要的 ),并通过 算法 将 下标中 不是素数的元素变成1,把是素数的数字放入 数组Prime 内
//效果大致如下,经过算法前:
// num = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0 .......0};
// 下标: 1 2 3 4 5 6 7 8 9 100010
//
//
// 经过算法后:
// num = {0, 1, 0, 0, 1, 0, 1, 0, 1, 1 .......0};
// 下标: 1 2 3 4 5 6 7 8 9 100010
//
//上面经过算法后 如果 数组内元素为0,就表示这 不是一个众数 (即素数)
// 如果 数组内元素为1,就表示这 是一个众数 (即不是素数)
int Prime[Max]; //创建一个 有Max个元素 每个元素为int类型 的数组
//作用:
//用于存放 在一定范围 筛选过后得到的素数
//最后 输出(打印)的是这个数组内的内容
int koudai; //存放 一开始输入的 口袋的承重量
int b = 0; //用来表示 数组Prime 中 空着位置的下标
//存放第一个素数时,b = 1,随后b++
//存放第二个素数时,b = 2,随后b++.......以此类推
//同理因为是全局变量,也可用于 得知 数组Prime内 存放了几个素数
//当运行到最后时,可用于得知 “口袋最多能装下的质数个数”
int c = 0; //用于应对本题要求—“口袋的负载量就是口袋里的所有数字之和”
//c 为 当前的 所有素数的和
void GetAllPrime(int koudai); //声明函数
int main()
{
scanf("%d", &koudai); //输入
GetAllPrime(koudai); //算法 函数
printf("%d", b); //打印 “口袋最多能装下的质数个数”
return 0;
}
/*
核心概念: 倍数 X 一个素数 = 一个众数
也就是说,可以通过 上面核心概念 来“筛”(干)掉 总数,只保留素数
*/
void GetAllPrime(int koudai) //算法 函数
{
num[1] = 1; //特例,表示1是一个众数
//刚刚处理了特例,要从2开始遍历
//这里的 i 主要用于充当 遍历数组num 的下标。
//因为“口袋的承重量有限”,所以i <= koudai
//同时 i 也用于充当 一个 “倍数” 的角色
for (int i = 2; i <= koudai; i++)
{
if (!(num[i])) //判断,如果 !(非) (一个素数) ,就执行下面{}内的内容
{
if ((c += i) > koudai) //判断 当前的 所有素数的和 是否大于 口袋的承重量
{
break; //跳出 最大的for循环
}
Prime[++b] = i; //b先自增,然后把 当前i的值 赋给 对应下标的数组Prime
printf("%d\n", Prime[b]); //打印
}
for (int j = 1; j <= b && i * Prime[j] <= koudai; j++) //这里的 j 主要用于充当 遍历数组Prime 的下标
{
num[i * Prime[j]] = 1; //最关键的部分,倍数(i) * 一个素数(Prime[j]),那么相乘计算后得到的 数组num的下标 是一个众数,让这个众数对应的元素变成1(筛掉)
if (i % Prime[j] == 0) //判断,如果 i 是 数组Prime 内其中一个素数的倍数,就跳出for循环
{
break;
}
}
}
}
其实文字可能真的很难描述清楚,建议的是F10和F11开逐句过,然后开三个及以上的监视窗口
一个用于看num的变化
一个用于看Prime的变化
还有一个看i, j, c等参数
然后自己一行一行推一小遍,慢慢理解
这是我当时自己写的图,可以参考
python:(欧拉筛,100分)
koudai = int(input(""))
def shai(koudai):
c = 0
b = 0
num = [0 for i in range(koudai + 1)] # 使用列表推导,创建一个有n + 1个元素的列表,并把每个元素初始化成0
Prime = [] # 创建一个空列表,用于后续添加 经过算法得到的 素数
for i in range(2, koudai + 1):
if num[i] == 0:
if (c + i) > koudai:
break;
Prime.append(i)
c = c + i
print(f"{Prime[b]}")
b = b + 1
for j in Prime:
if i * j > koudai:
break;
num[i * j] = 1
if i % j == 0:
break;
return Prime, len(Prime)
Prime, b = shai(koudai)
print(b)
欢迎各位大佬斧正