白天澜云 • 1个月前
/使用二分法准确计算k_min和k_max,避免浮点误差。 预先生成sum的质数表,范围到200。 直接遍历k生成平方数,而不是遍历所有i。 移除nm数组及相关逻辑,避免数组越界错误。 在计算各位数字之和时直接累加,不需要存储vector。 这样,时间复杂度将大大降低,因为循环次数从O(b-a)变为O(sqrt(b)-sqrt(a)) 而质数判断变为查表操作O(1)。/
using namespace std;
long long sqrt_ceil(long long x) {
if (x <= 0)
return 0;
long long l = 0, r = 1;
while (r * r < x)
r *= 2;
while (l < r) {
long long mid = (l + r) / 2;
if (mid * mid >= x) {
r = mid;
} else {
l = mid + 1;
}
}
return l;
}
long long sqrt_floor(long long x) {
if (x <= 0)
return 0;
long long l = 0, r = 1;
while (r * r <= x)
r *= 2;
while (l < r) {
long long mid = (l + r + 1) / 2;
if (mid * mid <= x) {
l = mid;
} else {
r = mid - 1;
}
}
return l;
}
bool is_prime(int num) {
if (num <= 1)
return false;
for (int i = 2; i * i <= num; ++i) {
if (num % i == 0)
return false;
}
return true;
}
int main() {
long long a, b;
scanf("%lld%lld", &a, &b);
bool prime_table[200] = {false};
for (int s = 2; s < 200; ++s) {
prime_table[s] = is_prime(s);
}
long long k_min = sqrt_ceil(a);
long long k_max = sqrt_floor(b);
bool found = false;
for (long long k = k_min; k <= k_max; ++k) {
long long num = k * k;
if (num < a || num > b)
continue;
int sum = 0;
long long temp = num;
while (temp > 0) {
sum += temp % 10;
temp /= 10;
}
if (sum >= 2 && sum < 200 && prime_table[sum]) {
printf("%lld ", num);
found = true;
}
}
if (!found)
printf("0");
return 0;
}
评论:
请先登录,才能进行评论