目录
HDU1032——The 3n + 1 problem
题目描述
运行代码
代码思路
HDU1033——Edge
题目描述
运行代码
代码思路
HDU1034——Candy Sharing Game
题目描述
运行代码
代码思路
HDU1032——The 3n + 1 problem
题目描述
Problem - 1032
运行代码
#include <iostream>
using namespace std;
int main() {int i, j, t, k;while (cin >> i >> j) {int u = i;int o = j;int max = 0;if (i > j) {t = i;i = j;j = t;}for (k = i; k <= j; k++) { // 从 i 到 j 寻找最大循环次数int p = k;int cn = 0;while (p != 1) {if (p % 2 != 0)p = 3 * p + 1;elsep = p / 2;cn++; // cn 记录每个数变成 1 所需要的最大循环次数}if (max < cn)max = cn;}cout << u << " " << o << " " << max + 1 << endl;}return 0;
}
代码思路
-
读取输入:代码从标准输入读取两个整数
i
和j
,这两个整数定义了我们感兴趣的一个范围。 -
交换输入:如果
i
大于j
,则交换它们的位置,确保i
总是小于或等于j
,这样在后续的循环中我们可以从i
到j
进行迭代。 -
初始化变量:
u
和o
分别存储了最初的i
和j
的值,以便在最后输出时使用;max
变量被初始化为0,用于记录在指定范围内所有数的Collatz序列中,序列长度的最大值。 -
遍历范围内的每一个数:从
i
到j
,对于范围内的每一个数k
,代码将计算其Collatz序列的长度。 -
计算Collatz序列长度:对于每个数
k
,初始化p
等于k
,并使用一个循环来生成Collatz序列,直到p
变为1。在这个过程中,如果p
是奇数,则更新p
为3 * p + 1
;如果是偶数,则更新p
为p / 2
。每次迭代,cn
(循环计数)都会增加,用于记录生成序列所需的步数。 -
更新最大序列长度:每次计算完一个数的序列长度后,检查
cn
是否大于当前已知的最大序列长度max
,如果是,则更新max
为cn
。 -
输出结果:在处理完所有数后,输出最初输入的两个数
u
和o
,以及最长序列的长度max + 1
(因为序列的初始步骤也算一步)。这里加1是因为循环从某个数开始,最终到达1,所以cn
记录的是到达1之前的步数,因此最终结果要加1。 -
循环继续或结束:由于
while
循环的存在,程序会持续读取和处理输入,直到没有更多的输入为止(例如,当标准输入结束时)。
HDU1033——Edge
题目描述
Problem - 1033
运行代码
#include <iostream>
#include <string>
using namespace std;
const int L = 0, R = 1, U = 2, D = 3; // 代表左右上下 4 方向
int dir_A[] = { U, D, R, L }; // 执行 A 右转操作时 4 个方向变为对应的 UDRL 方向
int dir_V[] = { D, U, L, R }; // 执行 V 左转操作时 4 个方向变为对应的 DULR 方向
int dx[] = { -10, 10, 0, 0 }; // 左右上下 4 方向对应的 X 坐标增量
int dy[] = { 0, 0, 10, -10 }; // y 增量void Edge(const string& com) {cout << "300 420 moveto" << endl;cout << "310 420 lineto" << endl;int x = 310, y = 420; // 初始的坐标int cur_dir = R; // 初始的方向始终向右for (char c : com) { // 遍历命令int new_dir; // 新的方向if (c == 'A') {new_dir = dir_A[cur_dir];x += dx[new_dir]; // 新方向 X 增量y += dy[new_dir]; // 新方向 Y 增量}else {new_dir = dir_V[cur_dir];x += dx[new_dir];y += dy[new_dir];}cur_dir = new_dir; // 更新当前方向cout << x << " " << y << " lineto" << endl;}cout << "stroke" << endl;cout << "showpage" << endl;
}int main() {string com;while (cin >> com) {Edge(com);}return 0;
}
代码思路
HDU1034——Candy Sharing Game
题目描述
Problem - 1034
运行代码
#include <iostream>
#include <cstdio>
#define N 100using namespace std;int main() {int s[N], n, i, k, t, p;while (scanf_s("%d", &n) == 1 && n) {for (i = 0; i < n; i++)scanf_s("%d", s + i);for (k = 1; ; k++) {t = s[n - 1] / 2; // 首先处理边界条件,存取最后一个人糖果数的一半for (i = 0; i < n; i++) {p = s[i] / 2; // 存取当前糖果数的一半用来给右边的同学s[i] = s[i] / 2 + t; // 自己减一半再加上左边同学给的一半t = p; // 给完一个同学换下一个if (s[i] % 2 != 0) // 当前处理完如果为奇数,收老师一个s[i]++;}t = s[0];bool isSame = true; // 增加一个标志变量来判断是否每个同学糖果数相同for (i = 1; i < n; i++) {if (s[0] != s[i]) {isSame = false;break;}}if (isSame) {break;}}printf("%d %d\n", k, t); // 输出游戏次数和每个人最终的糖果数}return 0;
}
代码思路
-
读取输入:代码从标准输入读取一组整数,第一个整数
n
表示参与游戏的小朋友的数量,接着读取n
个整数,表示每个小朋友初始拥有的糖果数。 -
初始化游戏状态:使用一个整型数组
s
存储每个小朋友的糖果数,数组s
的大小由宏N
决定,这里假设最多有100个小朋友参与游戏。 -
重新分配糖果:代码进入一个无限循环,开始重新分配糖果的过程。每一次循环代表游戏的一轮。
-
处理边界条件:在每轮开始时,处理边界条件,即最后一个小朋友糖果数的一半会被保留,用于在这一轮结束时给予第一个小朋友。
-
分配糖果的逻辑:对于每一个小朋友,他们将自己的糖果数分成两半,一半留给自身,另一半给予右边的小朋友。如果分配后糖果数为奇数,则额外获得一颗糖果,以确保糖果数为偶数。
-
检查游戏是否结束:每一轮结束后,检查所有小朋友的糖果数是否相同。为此,代码使用了一个布尔变量
isSame
来标记所有小朋友的糖果数是否一致。如果所有小朋友的糖果数相同,游戏结束,跳出循环。 -
输出结果:一旦游戏结束,输出游戏的轮数
k
和每个小朋友最终的糖果数t
。 -
循环处理多组数据:由于使用了
while
循环读取输入,代码可以连续处理多组数据,直到读取的n
为0或输入结束。