目录
HDU1097——A hard puzzle
题目描述
运行代码
#include <iostream>
using namespace std;
int main() {
int a, b;
while (cin >> a >> b) {
int last = 1;
a %= 10; // 只保留 a 的个位数字
while (b > 0) {
if (b & 1) { // 如果 b 的最低位是 1
last = (last * a) % 10; // 计算个位数字的乘积并取个位
}
a = (a * a) % 10; // 每次更新 a 的个位数字的平方的个位
b >>= 1; // b 右移一位
}
cout << last << endl;
}
return 0;
}
代码思路
-
首先定义了两个整数
a
和b
,用于接收输入的两个数。 -
在
while (cin >> a >> b)
中,只要能从标准输入成功读取两个整数到a
和b
,就会执行后面的代码。 -
定义
last
并初始化为1
,用于保存最终结果(即a
的b
次幂的最后一位数字)。 -
对
a
进行取模运算a %= 10
,只保留a
的个位数字。这是因为只需要关注最后一位数字,其他高位数字不影响结果。 -
然后通过一个
while
循环处理b
:- 当
b
的最低位是1
(即b & 1
为真)时,更新last
为(last * a) % 10
,即计算当前的个位数字乘积并取个位。 - 每次循环更新
a
为(a * a) % 10
,这是因为只关注个位数字,所以每次更新a
的平方的个位数字。 - 将
b
右移一位(b >>= 1
),以便检查下一位。
- 当
-
最后输出计算得到的
last
,即a
的b
次幂的最后一位数字。
HDU1098——Ignatius's puzzle
题目描述
![](https://i-blog.csdnimg.cn/direct/ee96aaeb224f47e6ac929d12ebf07359.png)
运行代码
#include <iostream>
using namespace std;
int main() {
int k, a;
while (cin >> k) {
a = 0;
for (int i = 1; i < 10000; i++) {
if ((i * 65 - 18) % k == 0) {
a = (i * 65 - 18) / k;
i = 10000; // 直接结束循环
}
}
if (a == 0) {
cout << "no" << endl;
} else {
cout << a << endl;
}
}
return 0;
}
代码思路
-
首先定义了两个整数
k
和a
。 -
通过一个
while
循环,只要能从标准输入成功读取一个整数到k
,就会执行后续的代码。 -
初始化
a
为0
。 -
然后通过一个
for
循环,从1
迭代到9999
:- 计算
i * 65 - 18
对k
取模的结果。 - 如果取模结果为
0
,说明找到了符合条件的i
,计算a
为(i * 65 - 18) / k
,然后通过将i
赋值为10000
直接结束for
循环。
- 计算
-
根据
a
的值进行判断:- 如果
a
仍然为0
,说明在循环中没有找到符合条件的i
,输出"no"
。 - 如果
a
不为0
,则输出计算得到的a
。
- 如果
HDU1099——Lottery
题目描述
http://acm.hdu.edu.cn/showproblem.php?pid=1099
运行代码
#include <iostream>
using namespace std;
#include<algorithm>
int gcd(int a, int b) {
if (b == 0) return a;
return gcd(b, a % b);
}
int main() {
int n;
while (cin >> n) { // 使用 cin 替代 scanf 进行输入
int a = 0, b = 0, ans = 1;
for (int i = 1; i < n; i++) {
ans += n / (n - i);
int m = n % (n - i); // 分子
if (m == 0) continue;
if (a == 0 && b == 0) {
a = n - i;
b = m;
int gd = gcd(a, b); // 这里需要在 C++ 中实现计算最大公约数的函数
a /= gd;
b /= gd;
}
else {
int gd = gcd(a, n - i); // 同样需要实现最大公约数函数
int lm = a * (n - i) / gd;
b = m * (lm / (n - i)) + b * (lm / a);
a = lm;
ans += b / a;
b %= a;
if (b == 0) a = 0;
else {
gd = gcd(a, b);
a /= gd;
b /= gd;
}
}
}
if (a == 0) {
cout << ans << endl;
}
else {
for (int i = 1; i < ans * 10; i *= 10)
cout << " ";
cout << b << endl;
cout << ans << " ";
for (int i = 1; i <= a; i *= 10)
cout << "-";
cout << endl;
for (int i = 1; i < ans * 10; i *= 10)
cout << " ";
cout << a << endl;
}
}
return 0;
}
代码思路
-
定义了一个自定义函数
gcd
,使用递归的方式实现欧几里得算法来计算两个数的最大公约数。- 如果除数
b
为0
,则返回被除数a
作为最大公约数。 - 否则,通过递归调用
gcd(b, a % b)
继续计算。
- 如果除数
-
在
main
函数中:- 首先,定义了变量
n
,并通过while (cin >> n)
循环不断读取用户输入的整数n
。 - 然后,初始化了变量
a
、b
和ans
。 - 在
for
循环中,从1
到n - 1
进行迭代:- 每次迭代计算
ans += n / (n - i)
。 - 计算余数
m = n % (n - i)
,如果余数为0
则跳过本次迭代。 - 当
a
和b
都为0
时,初始化a
和b
,并使用gcd
函数计算它们的最大公约数,然后进行约分。 - 否则,再次使用
gcd
函数计算相关值,进行一系列复杂的计算和更新操作,包括计算最小公倍数lm
,更新a
、b
和ans
的值,并进行约分处理。
- 每次迭代计算
- 根据
a
是否为0
,以不同的格式输出结果。如果a
为0
,直接输出ans
;否则,按照特定的格式输出ans
、b
和a
。
- 首先,定义了变量