这题要注意时间复杂度

白天澜云  •  1个月前


/使用二分法准确计算k_min和k_max,避免浮点误差。 预先生成sum的质数表,范围到200。 直接遍历k生成平方数,而不是遍历所有i。 移除nm数组及相关逻辑,避免数组越界错误。 在计算各位数字之和时直接累加,不需要存储vector。 这样,时间复杂度将大大降低,因为循环次数从O(b-a)变为O(sqrt(b)-sqrt(a)) 而质数判断变为查表操作O(1)。/

include

include

include

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;

}


评论:

请先登录,才能进行评论