跳过并跳转到主要内容
BigO

自幂数判断

判断输入的 M 个小于 10^8 的正整数是否为自幂数:即对于一个 N 位数,若其各位数字的 N 次方之和恰好等于该数本身(如 153 = 1^3 + 5^3 + 3^3),则按顺序输出 `T`,否则输出 `F`。

GESP1分钟阅读

  1. 确定位数 NN:求出当前正整数的位数 NN(可以转成字符串求长度,或通过不断除以 1010 统计位数)。
  2. 计算各位数字的 NN 次方和:逐位取出数字,求该数字的 NN 次方(或用循环连乘 NN 次),并累加到总和中。
  3. 判断并输出:比较累加和与原数值是否相等,相等则输出 T,否则输出 F。

在具体实现时,有两种常见的处理方式:

方法一:字符串转化法(直观易写)

将输入的数字直接作为字符串 string 读入:

  • 位数 NN:即为字符串长度 s.length()。
  • 按位提取:遍历字符串的每个字符 c,用 c - '0' 转化为对应数字。
  • 注意点:需要用 stoll 将原字符串转为整数,用于最后的相等判断。

方法二:纯数学取模法(基础数论)

直接将数值作为整数 long long 读入,通过数字运算处理:

  • 位数 NN:利用 while (temp > 0) 循环不断 temp /= 10,统计相除的次数。
  • 按位提取:利用 temp % 10 取出当前最低位,再通过 temp /= 10 剥离最低位,依次累加其 NN 次方。

#include <iostream>
#include <string>
#include <cmath>
using namespace std;
void solve() {
string s;
cin >> s;
int n = s.length(); // 获取位数 N
long long original = stoll(s); // 转为整数便于最后比较
long long sum = 0;
// 计算每位数字的 N 次方之和
for (char c : s) {
int digit = c - '0';
sum += round(pow(digit, n)); // 使用 round 防止浮点数精度误差
}
// 判断并输出结果
if (sum == original) {
cout << "T" << endl;
} else {
cout << "F" << endl;
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int m;
cin >> m;
while (m--) {
solve();
}
return 0;
}

#include <iostream>
#include <cmath>
using namespace std;
void solve() {
long long x;
cin >> x;
long long temp = x;
int n = 0;
// 1. 统计位数 N
while (temp > 0) {
n++;
temp /= 10;
}
// 2. 取每位数字并计算 N 次方之和
temp = x;
long long sum = 0;
while (temp > 0) {
int digit = temp % 10; // 取当前最低位数字
sum += round(pow(digit, n)); // 使用 round 避免浮点数精度误差
temp /= 10; // 抹掉最低位
}
// 3. 判断并输出结果
if (sum == x) {
cout << "T\n";
} else {
cout << "F\n";
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int m;
cin >> m;
while (m--) {
solve();
}
return 0;
}

  • 时间复杂度:O(M×log⁡10X)\mathcal{O}(M \times \log_{10} X)。对于每个待测数字 XX,提取位数和按位计算的次数等于 XX 的十进制位数(最高为 88 位)。在 M≤100M \le 100 的数据范围内,总计算量不超过 10310^3 次,轻松在 1.00s1.00\text{s} 内通过。
  • 空间复杂度:O(1)\mathcal{O}(1)。仅占用常数级别的临时变量空间。

© 2026 三七开 · 一方通行,只管向前。

旅途由 Astro 驱动 · 主题 Chirping Astro