文章目录
-
- 概要
- 整体架构流程
- 技术名词解释
- 技术细节
- 小结
1. 概要
~ Jack Qiao对米粒说:“今天咱们玩个小游戏,这个游戏的玩家需要猜出,两个随机生成的整数的最大公约数(GCD)和最小公倍数(LCM)。如果猜对了,就给予奖励,猜错了则给出提示。
~ 米粒思考后,想到有以下模块:
> 随机数生成、函数、最大公约数(GCD)、最小公倍数(LCM)、输入输出、控制结构等知识。
2. 整体架构流程
2.1. 计算最大公约数(GCD)
- 概念: 最大公约数是能够同时整除两个或多个整数的最大正整数。
int gcd(int a, int b) {while (b != 0) {int temp = b;b = a % b;a = temp;}return a; }
> 这里的while (b != 0),这个 while 循环会一直执行,直到 b 变为 0。
> 循环的目的是通过不断地更新 a 和 b,最终使得 b 变为 0。
> int temp = b; 创建一个临时变量 temp,并将其赋值为 b 的当前值。
b = a % b; 将 b 更新为 a 除以 b 的余数。
a = temp; 将 a 更新为之前的 b 值(即 temp)。
~ 循环的目的是通过不断地更新 a 和 b,最终使得 b 变为 0。
2.2. 计算最小公倍数(LCM)
- 概念: 最小公倍数是能够同时被两个或多个整数整除的最小正整数。
int lcm(int a, int b) {return (a * b) / gcd(a, b); }
> 先计算两个数的最大公约数 gcd(a, b),然后用两个数的乘积除以最大公约数得到最小公倍数。
2.3. main函数
int main() {int num1, num2;int gcd_result, lcm_result;int user_gcd_guess, user_lcm_guess;char play_again;// 初始化随机数生成器srand(time(NULL));// 游戏主循环do {// 生成两个随机数num1 = rand() % 50 + 1; // 生成1到50之间的随机数num2 = rand() % 50 + 1;// 显示随机生成的两个数printf("随机生成的两个数是: %d 和 %d\n", num1, num2);// 计算最大公约数和最小公倍数gcd_result = gcd(num1, num2);lcm_result = lcm(num1, num2);// 让用户猜测最大公约数printf("请猜这两个数的最大公约数: ");scanf("%d", &user_gcd_guess);// 检查用户的猜测是否正确if (user_gcd_guess == gcd_result) {printf("恭喜你,猜对了!最大公约数确实是 %d。\n", gcd_result);}else {printf("很遗憾,猜错了。最大公约数是 %d。\n", gcd_result);}// 让用户猜测最小公倍数printf("请猜这两个数的最小公倍数: ");scanf("%d", &user_lcm_guess);// 检查用户的猜测是否正确if (user_lcm_guess == lcm_result) {printf("恭喜你,猜对了!最小公倍数确实是 %d。\n", lcm_result);}else {printf("很遗憾,猜错了。最小公倍数是 %d。\n", lcm_result);}// 询问用户是否想再次玩游戏printf("你想再玩一次吗?(y/n): ");scanf(" %c", &play_again);} while (play_again == 'y' || play_again == 'Y');printf("谢谢你的参与!再见!\n");return 0; }
2.3.1. 随机数生成
- 函数: srand() 和 rand()
- srand(time(NULL)): 初始化随机数生成器,使用当前时间作为种子,确保每次运行程序时生成的随机数序列不同。
- rand() % 50 + 1: 生成1到50之间的随机数。
2.3.2. 控制结构
> 循环:使用 do-while 循环实现游戏的主循环,确保至少执行一次。
do {// 游戏逻辑 } while (play_again == 'y' || play_again == 'Y');
2.4. 运行结果
2.5. 全部代码
#include <stdio.h>
#include <stdlib.h>
#include <time.h>// 定义一个函数来计算最大公约数(GCD)
int gcd(int a, int b) {
while (b != 0) {
int temp = b;
b = a % b;
a = temp;
}
return a;
}// 定义一个函数来计算最小公倍数(LCM)
int lcm(int a, int b) {
return (a * b) / gcd(a, b);
}int main() {
int num1, num2;
int gcd_result, lcm_result;
int user_gcd_guess, user_lcm_guess;
char play_again;// 初始化随机数生成器
srand(time(NULL));// 游戏主循环
do {
// 生成两个随机数
num1 = rand() % 50 + 1; // 生成1到50之间的随机数
num2 = rand() % 50 + 1;// 显示随机生成的两个数
printf("随机生成的两个数是: %d 和 %d\n", num1, num2);// 计算最大公约数和最小公倍数
gcd_result = gcd(num1, num2);
lcm_result = lcm(num1, num2);// 让用户猜测最大公约数
printf("请猜这两个数的最大公约数: ");
scanf("%d", &user_gcd_guess);// 检查用户的猜测是否正确
if (user_gcd_guess == gcd_result) {
printf("恭喜你,猜对了!最大公约数确实是 %d。\n", gcd_result);
}
else {
printf("很遗憾,猜错了。最大公约数是 %d。\n", gcd_result);
}// 让用户猜测最小公倍数
printf("请猜这两个数的最小公倍数: ");
scanf("%d", &user_lcm_guess);// 检查用户的猜测是否正确
if (user_lcm_guess == lcm_result) {
printf("恭喜你,猜对了!最小公倍数确实是 %d。\n", lcm_result);
}
else {
printf("很遗憾,猜错了。最小公倍数是 %d。\n", lcm_result);
}// 询问用户是否想再次玩游戏
printf("你想再玩一次吗?(y/n): ");
scanf(" %c", &play_again);} while (play_again == 'y' || play_again == 'Y');
printf("谢谢你的参与!再见!\n");
return 0;
}
3. 技术名词解释
> 计算最大公约数(GCD),最大公约数是能够同时整除两个或多个整数的最大正整数。
> 计算最小公倍数(LCM),最小公倍数是能够同时被两个或多个整数整除的最小正整数。
4. 技术细节
~ 在每次循环中:
> 让用户猜测最小公倍数,并检查用户的猜测是否正确。
> 让用户猜测最大公约数,并检查用户的猜测是否正确。
> 计算这两个数的最大公约数和最小公倍数。
> 显示这两个随机数。
> 生成两个1到50之间的随机数 num1 和 num2。
5. 小结
~ 米粒最后对该游戏做了如下总结
该游戏通过生成两个1到50之间的随机数,利用欧几里得算法计算最大公约数(GCD)和公式 `(a * b) / gcd(a, b)计算最小公倍数(LCM),并通过 `printf` 和 `scanf` 函数实现用户交互,使用 `do-while` 循环和 `if-else` 语句控制游戏流程,确保用户可以多次猜测并获得即时反馈。