问题如果数字的总和以及数字的平方和是素数,则该数字称为幸运数字。多少 A和B之间的数字是幸运的吗?
输入:第一行包含测试用例数T.每个下一个T行包含两个整数,A和B.
输出:输出T行,每个案例一行,包含相应案例的必要答案。
约束:
1< = T< = 10000
1< = A< = B< = 10 ^ 18示例输入:
2
1 20
120 130
示例输出:
4
1
说明:对于第一种情况,幸运数字是11,12,14,16。对于第二种情况,唯一的幸运数字是120.
如果我们使用蛮力,问题很简单,但是运行时间非常重要,以至于我的程序在大多数测试用例中都失败了。我目前的想法是通过将先前的和存储在临时数组中来使用动态编程,例如:
sum_digits(10) = 1 -> sum_digits(11) = sum_digits(10) + 1
同样的想法适用于求和方,但计数器等于奇数。不幸的是,它仍然失败了10个测试用例中的9个,这让我觉得必须有更好的方法来解决它。任何想法都将不胜感激。
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <unordered_map>
#include <unordered_set>
#include <cmath>
#include <cassert>
#include <bitset>
using namespace std;
bool prime_table[1540] = {
0, 0, 1, 1, 0, 1, 0, 1, 0,
0, 0, 1, 0, 1, 0, 0, 0, 1, 0,
1, 0, 0, 0, 1, 0, 0, 0, 0, 0,
1, 0, 1, 0, 0, 0, 0, 0, 1, 0,
0, 0, 1, 0, 1, 0, 0, 0, 1, 0,
0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
1, 0, 1, 0, 0, 0, 0, 0, 1, 0,
0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
1, 0, 0, 0, 1, 0, 0, 0, 0, 0,
1, 0, 0, 0, 0, 0, 0, 0, 1, 0,
0, 0, 1, 0, 1, 0, 0, 0, 1, 0,
1, 0, 0, 0, 1, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
0, 0, 1, 0, 0, 0, 0, 0, 1, 0,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 0, 1, 0, 0, 0, 0, 0, 1, 0,
0, 0, 0, 0, 1, 0, 0, 0, 1, 0,
0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
1, 0, 1, 0, 0, 0, 0, 0, 0, 0,
0, 0, 1, 0, 1, 0, 0, 0, 1, 0,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 1, 0, 0, 0, 1, 0,
1, 0, 0, 0, 1, 0, 0, 0, 0, 0,
1, 0, 1, 0, 0, 0, 0, 0, 0, 0,
0, 0, 1, 0, 0, 0, 0, 0, 1, 0,
0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
1, 0, 1, 0, 0, 0, 0, 0, 1, 0,
0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
0, 0, 1, 0, 1, 0, 0, 0, 1, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 1, 0, 0, 0, 0, 0, 1, 0,
0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
1, 0, 0, 0, 1, 0, 0, 0, 0, 0,
1, 0, 0, 0, 0, 0, 0, 0, 1, 0,
0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
1, 0, 0, 0, 1, 0, 0, 0, 0, 0,
1, 0, 0, 0, 0, 0, 0, 0, 1, 0,
0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 0, 1, 0, 0, 0, 0, 0, 0, 0,
0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
1, 0, 0, 0, 1, 0, 0, 0, 0, 0,
1, 0, 0, 0, 0, 0, 0, 0, 1, 0,
0, 0, 1, 0, 1, 0, 0, 0, 1, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 0, 0, 0, 0, 0, 0, 0, 1, 0,
0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
1, 0, 0, 0, 1, 0, 0, 0, 0, 0,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 1, 0, 0, 0, 0, 0, 1, 0,
0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
1, 0, 1, 0, 0, 0, 0, 0, 1, 0,
0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
1, 0, 1, 0, 0, 0, 0, 0, 1, 0,
0, 0, 0, 0, 1, 0, 0, 0, 1, 0,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
0, 0, 1, 0, 1, 0, 0, 0, 1, 0,
0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
1, 0, 1, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 1, 0, 0, 0, 1, 0,
0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 0, 0, 0, 0, 0, 0, 0, 1, 0,
0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
1, 0, 0, 0, 1, 0, 0, 0, 0, 0,
0, 0, 1, 0, 0, 0, 0, 0, 1, 0,
0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
1, 0, 0, 0, 1, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 0, 1, 0, 0, 0, 0, 0, 0, 0,
0, 0, 1, 0, 1, 0, 0, 0, 1, 0,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 1, 0, 0, 0, 1, 0,
1, 0, 0, 0, 1, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
0, 0, 1, 0, 1, 0, 0, 0, 1, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 0, 0, 0, 0, 0, 0, 0, 1, 0,
0, 0, 1, 0, 0, 0, 0, 0, 1, 0,
0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
0, 0, 1, 0, 0, 0, 0, 0, 1, 0,
0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
0, 0, 1, 0, 0, 0, 0, 0, 1, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 0, 0, 0, 1, 0, 0, 0, 0, 0,
1, 0, 1, 0, 0, 0, 0, 0, 0, 0,
0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 0, 1, 0, 0, 0, 0, 0, 0, 0,
0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
0, 0, 1, 0, 1, 0, 0, 0, 1, 0,
0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
1, 0, 0, 0, 0, 0, 0, 0, 1, 0,
0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
0, 0, 1, 0, 0, 0, 0, 0, 1, 0,
0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 1, 0, 0, 0, 1, 0,
0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
1, 0, 1, 0, 0, 0, 0, 0, 1, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
1, 0, 0, 0, 1, 0, 0, 0, 0, 0,
1, 0, 1, 0, 0, 0, 0, 0, 1, 0,
0, 0, 1, 0, 1, 0, 0, 0, 1, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 0, 1, 0, 0, 0, 0, 0, 1, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 1, 0, 0, 0, 0, 0, 1, 0,
0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 1, 0, 0, 0, 1, 0,
1, 0, 0, 0, 1, 0, 0, 0, 0, 0,
1, 0, 0, 0, 0, 0, 0, 0, 1, 0,
0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
0, 0, 1, 0, 1, 0, 0, 0, 1, 0,
1, 0, 0, 0, 1, 0, 0, 0, 0, 0,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
0
};
unsigned num_digits(long long i) {
return i > 0 ? (long) log10 ((double) i) + 1 : 1;
}
void get_sum_and_sum_square_digits(long long n, int& sum, int& sum_square) {
sum = 0;
sum_square = 0;
int digit;
while (n) {
digit = n % 10;
sum += digit;
sum_square += digit * digit;
n /= 10;
}
}
void init_digits(long long n, long long previous_sum[], const int size = 18) {
int current_no_digits = num_digits(n);
int digit;
for (int i = 0; i < current_no_digits; ++i) {
digit = n % 10;
previous_sum[i] = digit;
n /= 10;
}
for (int i = current_no_digits; i <= size; ++i) {
previous_sum[i] = 0;
}
}
void display_previous(long long previous[]) {
for (int i = 0; i < 18; ++i) {
cout << previous[i] << ",";
}
}
int count_lucky_number(long long A, long long B) {
long long n = A;
long long end = B;
int sum = 0;
int sum_square = 0;
int lucky_counter = 0;
get_sum_and_sum_square_digits(n, sum, sum_square);
long long sum_counter = sum;
long long sum_square_counter = sum_square;
if (prime_table[sum_counter] && prime_table[sum_square_counter]) {
lucky_counter++;
}
long long previous_sum[19] = {1};
init_digits(n, previous_sum);
while (n < end) {
n++;
if (n % 100000000000000000 == 0) {
previous_sum[17]++;
sum_counter = previous_sum[17] + previous_sum[18];
sum_square_counter = previous_sum[17] * previous_sum[17] + previous_sum[18] * previous_sum[18];
previous_sum[16] = 0;
previous_sum[15] = 0;
previous_sum[14] = 0;
previous_sum[13] = 0;
previous_sum[12] = 0;
previous_sum[11] = 0;
previous_sum[10] = 0;
previous_sum[9] = 0;
previous_sum[8] = 0;
previous_sum[7] = 0;
previous_sum[6] = 0;
previous_sum[5] = 0;
previous_sum[4] = 0;
previous_sum[3] = 0;
previous_sum[2] = 0;
previous_sum[1] = 0;
previous_sum[0] = 0;
}
else if (n % 10000000000000000 == 0) {
previous_sum[16]++;
sum_counter = previous_sum[16] + previous_sum[17] + previous_sum[18];
sum_square_counter =
previous_sum[16] * previous_sum[16] +
previous_sum[17] * previous_sum[17] +
previous_sum[18] * previous_sum[18];
previous_sum[15] = 0;
previous_sum[14] = 0;
previous_sum[13] = 0;
previous_sum[12] = 0;
previous_sum[11] = 0;
previous_sum[10] = 0;
previous_sum[9] = 0;
previous_sum[8] = 0;
previous_sum[7] = 0;
previous_sum[6] = 0;
previous_sum[5] = 0;
previous_sum[4] = 0;
previous_sum[3] = 0;
previous_sum[2] = 0;
previous_sum[1] = 0;
previous_sum[0] = 0;
}
else if (n % 1000000000000000 == 0) {
previous_sum[15]++;
sum_counter = previous_sum[15] + previous_sum[16] + previous_sum[17] + previous_sum[18];
sum_square_counter =
previous_sum[15] * previous_sum[15] +
previous_sum[16] * previous_sum[16] +
previous_sum[17] * previous_sum[17] +
previous_sum[18] * previous_sum[18];
previous_sum[14] = 0;
previous_sum[13] = 0;
previous_sum[12] = 0;
previous_sum[11] = 0;
previous_sum[10] = 0;
previous_sum[9] = 0;
previous_sum[8] = 0;
previous_sum[7] = 0;
previous_sum[6] = 0;
previous_sum[5] = 0;
previous_sum[4] = 0;
previous_sum[3] = 0;
previous_sum[2] = 0;
previous_sum[1] = 0;
previous_sum[0] = 0;
}
else if (n % 100000000000000 == 0) {
previous_sum[14]++;
sum_counter = previous_sum[14] + previous_sum[15] + previous_sum[16] + previous_sum[17] + previous_sum[18];
sum_square_counter =
previous_sum[14] * previous_sum[14] +
previous_sum[15] * previous_sum[15] +
previous_sum[16] * previous_sum[16] +
previous_sum[17] * previous_sum[17] +
previous_sum[18] * previous_sum[18];
previous_sum[13] = 0;
previous_sum[12] = 0;
previous_sum[11] = 0;
previous_sum[10] = 0;
previous_sum[9] = 0;
previous_sum[8] = 0;
previous_sum[7] = 0;
previous_sum[6] = 0;
previous_sum[5] = 0;
previous_sum[4] = 0;
previous_sum[3] = 0;
previous_sum[2] = 0;
previous_sum[1] = 0;
previous_sum[0] = 0;
}
else if (n % 10000000000000 == 0) {
previous_sum[13]++;
sum_counter = previous_sum[13] + previous_sum[14] + previous_sum[15] + previous_sum[16] + previous_sum[17] + previous_sum[18];
sum_square_counter =
previous_sum[13] * previous_sum[13] +
previous_sum[14] * previous_sum[14] +
previous_sum[15] * previous_sum[15] +
previous_sum[16] * previous_sum[16] +
previous_sum[17] * previous_sum[17] +
previous_sum[18] * previous_sum[18];
previous_sum[12] = 0;
previous_sum[11] = 0;
previous_sum[10] = 0;
previous_sum[9] = 0;
previous_sum[8] = 0;
previous_sum[7] = 0;
previous_sum[6] = 0;
previous_sum[5] = 0;
previous_sum[4] = 0;
previous_sum[3] = 0;
previous_sum[2] = 0;
previous_sum[1] = 0;
previous_sum[0] = 0;
}
else if (n % 1000000000000 == 0) {
previous_sum[12]++;
sum_counter = previous_sum[12] + previous_sum[13] + previous_sum[14] + previous_sum[15] + previous_sum[16] + previous_sum[17] + previous_sum[18];
sum_square_counter =
previous_sum[12] * previous_sum[12] +
previous_sum[13] * previous_sum[13] +
previous_sum[14] * previous_sum[14] +
previous_sum[15] * previous_sum[15] +
previous_sum[16] * previous_sum[16] +
previous_sum[17] * previous_sum[17] +
previous_sum[18] * previous_sum[18];
previous_sum[11] = 0;
previous_sum[10] = 0;
previous_sum[9] = 0;
previous_sum[8] = 0;
previous_sum[7] = 0;
previous_sum[6] = 0;
previous_sum[5] = 0;
previous_sum[4] = 0;
previous_sum[3] = 0;
previous_sum[2] = 0;
previous_sum[1] = 0;
previous_sum[0] = 0;
}
else if (n % 100000000000 == 0) {
previous_sum[11]++;
sum_counter =
previous_sum[11] + previous_sum[12] + previous_sum[13] + previous_sum[14] + previous_sum[15] + previous_sum[16] + previous_sum[17] + previous_sum[18];
sum_square_counter =
previous_sum[11] * previous_sum[11] +
previous_sum[12] * previous_sum[12] +
previous_sum[13] * previous_sum[13] +
previous_sum[14] * previous_sum[14] +
previous_sum[15] * previous_sum[15] +
previous_sum[16] * previous_sum[16] +
previous_sum[17] * previous_sum[17] +
previous_sum[18] * previous_sum[18];
previous_sum[10] = 0;
previous_sum[9] = 0;
previous_sum[8] = 0;
previous_sum[7] = 0;
previous_sum[6] = 0;
previous_sum[5] = 0;
previous_sum[4] = 0;
previous_sum[3] = 0;
previous_sum[2] = 0;
previous_sum[1] = 0;
previous_sum[0] = 0;
}
else if (n % 10000000000 == 0) {
previous_sum[10]++;
sum_counter =
previous_sum[10] +
previous_sum[11] + previous_sum[12] + previous_sum[13] + previous_sum[14] + previous_sum[15] +
previous_sum[16] + previous_sum[17] + previous_sum[18];
sum_square_counter =
previous_sum[10] * previous_sum[10] +
previous_sum[11] * previous_sum[11] +
previous_sum[12] * previous_sum[12] +
previous_sum[13] * previous_sum[13] +
previous_sum[14] * previous_sum[14] +
previous_sum[15] * previous_sum[15] +
previous_sum[16] * previous_sum[16] +
previous_sum[17] * previous_sum[17] +
previous_sum[18] * previous_sum[18];
previous_sum[9] = 0;
previous_sum[8] = 0;
previous_sum[7] = 0;
previous_sum[6] = 0;
previous_sum[5] = 0;
previous_sum[4] = 0;
previous_sum[3] = 0;
previous_sum[2] = 0;
previous_sum[1] = 0;
previous_sum[0] = 0;
}
else if (n % 1000000000 == 0) {
previous_sum[9]++;
sum_counter =
previous_sum[9] + previous_sum[10] +
previous_sum[11] + previous_sum[12] + previous_sum[13] + previous_sum[14] + previous_sum[15] +
previous_sum[16] + previous_sum[17] + previous_sum[18];
sum_square_counter =
previous_sum[9] * previous_sum[9] +
previous_sum[10] * previous_sum[10] +
previous_sum[11] * previous_sum[11] +
previous_sum[12] * previous_sum[12] +
previous_sum[13] * previous_sum[13] +
previous_sum[14] * previous_sum[14] +
previous_sum[15] * previous_sum[15] +
previous_sum[16] * previous_sum[16] +
previous_sum[17] * previous_sum[17] +
previous_sum[18] * previous_sum[18];
previous_sum[8] = 0;
previous_sum[7] = 0;
previous_sum[6] = 0;
previous_sum[5] = 0;
previous_sum[4] = 0;
previous_sum[3] = 0;
previous_sum[2] = 0;
previous_sum[1] = 0;
previous_sum[0] = 0;
}
else if (n % 100000000 == 0) {
previous_sum[8]++;
sum_counter =
previous_sum[8] + previous_sum[9] + previous_sum[10] +
previous_sum[11] + previous_sum[12] + previous_sum[13] + previous_sum[14] + previous_sum[15] +
previous_sum[16] + previous_sum[17] + previous_sum[18];
sum_square_counter =
previous_sum[8] * previous_sum[8] +
previous_sum[9] * previous_sum[9] +
previous_sum[10] * previous_sum[10] +
previous_sum[11] * previous_sum[11] +
previous_sum[12] * previous_sum[12] +
previous_sum[13] * previous_sum[13] +
previous_sum[14] * previous_sum[14] +
previous_sum[15] * previous_sum[15] +
previous_sum[16] * previous_sum[16] +
previous_sum[17] * previous_sum[17] +
previous_sum[18] * previous_sum[18];
previous_sum[7] = 0;
previous_sum[6] = 0;
previous_sum[5] = 0;
previous_sum[4] = 0;
previous_sum[3] = 0;
previous_sum[2] = 0;
previous_sum[1] = 0;
previous_sum[0] = 0;
}
else if (n % 10000000 == 0) {
previous_sum[7]++;
sum_counter =
previous_sum[7] + previous_sum[8] + previous_sum[9] + previous_sum[10] +
previous_sum[11] + previous_sum[12] + previous_sum[13] + previous_sum[14] + previous_sum[15] +
previous_sum[16] + previous_sum[17] + previous_sum[18];
sum_square_counter =
previous_sum[7] * previous_sum[7] +
previous_sum[8] * previous_sum[8] +
previous_sum[9] * previous_sum[9] +
previous_sum[10] * previous_sum[10] +
previous_sum[11] * previous_sum[11] +
previous_sum[12] * previous_sum[12] +
previous_sum[13] * previous_sum[13] +
previous_sum[14] * previous_sum[14] +
previous_sum[15] * previous_sum[15] +
previous_sum[16] * previous_sum[16] +
previous_sum[17] * previous_sum[17] +
previous_sum[18] * previous_sum[18];
previous_sum[6] = 0;
previous_sum[5] = 0;
previous_sum[4] = 0;
previous_sum[3] = 0;
previous_sum[2] = 0;
previous_sum[1] = 0;
previous_sum[0] = 0;
}
else if (n % 1000000 == 0) {
previous_sum[6]++;
sum_counter =
previous_sum[6] + previous_sum[7] + previous_sum[8] + previous_sum[9] + previous_sum[10] +
previous_sum[11] + previous_sum[12] + previous_sum[13] + previous_sum[14] + previous_sum[15] +
previous_sum[16] + previous_sum[17] + previous_sum[18];
sum_square_counter =
previous_sum[6] * previous_sum[6] +
previous_sum[7] * previous_sum[7] +
previous_sum[8] * previous_sum[8] +
previous_sum[9] * previous_sum[9] +
previous_sum[10] * previous_sum[10] +
previous_sum[11] * previous_sum[11] +
previous_sum[12] * previous_sum[12] +
previous_sum[13] * previous_sum[13] +
previous_sum[14] * previous_sum[14] +
previous_sum[15] * previous_sum[15] +
previous_sum[16] * previous_sum[16] +
previous_sum[17] * previous_sum[17] +
previous_sum[18] * previous_sum[18];
previous_sum[5] = 0;
previous_sum[4] = 0;
previous_sum[3] = 0;
previous_sum[2] = 0;
previous_sum[1] = 0;
previous_sum[0] = 0;
}
else if (n % 100000 == 0) {
previous_sum[5]++;
sum_counter = previous_sum[5] + previous_sum[6] + previous_sum[7] + previous_sum[8] + previous_sum[9] + previous_sum[10] + previous_sum[11] + previous_sum[12] + previous_sum[13] + previous_sum[14] + previous_sum[15] + previous_sum[16] + previous_sum[17] + previous_sum[18];
sum_square_counter =
previous_sum[5] * previous_sum[5] +
previous_sum[6] * previous_sum[6] +
previous_sum[7] * previous_sum[7] +
previous_sum[8] * previous_sum[8] +
previous_sum[9] * previous_sum[9] +
previous_sum[10] * previous_sum[10] +
previous_sum[11] * previous_sum[11] +
previous_sum[12] * previous_sum[12] +
previous_sum[13] * previous_sum[13] +
previous_sum[14] * previous_sum[14] +
previous_sum[15] * previous_sum[15] +
previous_sum[16] * previous_sum[16] +
previous_sum[17] * previous_sum[17] +
previous_sum[18] * previous_sum[18];
previous_sum[4] = 0;
previous_sum[3] = 0;
previous_sum[2] = 0;
previous_sum[1] = 0;
previous_sum[0] = 0;
}
else if (n % 10000 == 0) {
previous_sum[4]++;
sum_counter =
previous_sum[4] + previous_sum[5] +
previous_sum[6] + previous_sum[7] + previous_sum[8] + previous_sum[9] + previous_sum[10] +
previous_sum[11] + previous_sum[12] + previous_sum[13] + previous_sum[14] + previous_sum[15] +
previous_sum[16] + previous_sum[17] + previous_sum[18];
sum_square_counter =
previous_sum[4] * previous_sum[4] +
previous_sum[5] * previous_sum[5] +
previous_sum[6] * previous_sum[6] +
previous_sum[7] * previous_sum[7] +
previous_sum[8] * previous_sum[8] +
previous_sum[9] * previous_sum[9] +
previous_sum[12] * previous_sum[12] +
previous_sum[13] * previous_sum[13] +
previous_sum[14] * previous_sum[14] +
previous_sum[15] * previous_sum[15] +
previous_sum[16] * previous_sum[16] +
previous_sum[17] * previous_sum[17] +
previous_sum[18] * previous_sum[18];
previous_sum[3] = 0;
previous_sum[2] = 0;
previous_sum[1] = 0;
previous_sum[0] = 0;
}
else if (n % 1000 == 0) {
previous_sum[3]++;
sum_counter =
previous_sum[3] + previous_sum[4] + previous_sum[5] +
previous_sum[6] + previous_sum[7] + previous_sum[8] + previous_sum[9] + previous_sum[10] +
previous_sum[11] + previous_sum[12] + previous_sum[13] + previous_sum[14] + previous_sum[15] +
previous_sum[16] + previous_sum[17] + previous_sum[18];
sum_square_counter =
previous_sum[3] * previous_sum[3] +
previous_sum[4] * previous_sum[4] +
previous_sum[5] * previous_sum[5] +
previous_sum[6] * previous_sum[6] +
previous_sum[7] * previous_sum[7] +
previous_sum[8] * previous_sum[8] +
previous_sum[9] * previous_sum[9] +
previous_sum[10] * previous_sum[10] +
previous_sum[11] * previous_sum[11] +
previous_sum[12] * previous_sum[12] +
previous_sum[13] * previous_sum[13] +
previous_sum[14] * previous_sum[14] +
previous_sum[15] * previous_sum[15] +
previous_sum[16] * previous_sum[16] +
previous_sum[17] * previous_sum[17] +
previous_sum[18] * previous_sum[18];
previous_sum[2] = 0;
previous_sum[1] = 0;
previous_sum[0] = 0;
}
else if (n % 100 == 0) {
previous_sum[2]++;
sum_counter =
previous_sum[2] + previous_sum[3] + previous_sum[4] + previous_sum[5] +
previous_sum[6] + previous_sum[7] + previous_sum[8] + previous_sum[9] + previous_sum[10] +
previous_sum[11] + previous_sum[12] + previous_sum[13] + previous_sum[14] + previous_sum[15] +
previous_sum[16] + previous_sum[17] + previous_sum[18];
sum_square_counter =
previous_sum[2] * previous_sum[2] +
previous_sum[3] * previous_sum[3] +
previous_sum[4] * previous_sum[4] +
previous_sum[5] * previous_sum[5] +
previous_sum[6] * previous_sum[6] +
previous_sum[7] * previous_sum[7] +
previous_sum[8] * previous_sum[8] +
previous_sum[9] * previous_sum[9] +
previous_sum[10] * previous_sum[10] +
previous_sum[11] * previous_sum[11] +
previous_sum[12] * previous_sum[12] +
previous_sum[13] * previous_sum[13] +
previous_sum[14] * previous_sum[14] +
previous_sum[15] * previous_sum[15] +
previous_sum[16] * previous_sum[16] +
previous_sum[17] * previous_sum[17] +
previous_sum[18] * previous_sum[18];
previous_sum[1] = 0;
previous_sum[0] = 0;
}
else if (n % 10 == 0) {
previous_sum[1]++;
sum_counter =
previous_sum[1] + previous_sum[2] + previous_sum[3] + previous_sum[4] + previous_sum[5] +
previous_sum[6] + previous_sum[7] + previous_sum[8] + previous_sum[9] + previous_sum[10] +
previous_sum[11] + previous_sum[12] + previous_sum[13] + previous_sum[14] + previous_sum[15] +
previous_sum[16] + previous_sum[17] + previous_sum[18];
sum_square_counter =
previous_sum[1] * previous_sum[1] +
previous_sum[2] * previous_sum[2] +
previous_sum[3] * previous_sum[3] +
previous_sum[4] * previous_sum[4] +
previous_sum[5] * previous_sum[5] +
previous_sum[6] * previous_sum[6] +
previous_sum[7] * previous_sum[7] +
previous_sum[8] * previous_sum[8] +
previous_sum[9] * previous_sum[9] +
previous_sum[10] * previous_sum[10] +
previous_sum[11] * previous_sum[11] +
previous_sum[12] * previous_sum[12] +
previous_sum[13] * previous_sum[13] +
previous_sum[14] * previous_sum[14] +
previous_sum[15] * previous_sum[15] +
previous_sum[16] * previous_sum[16] +
previous_sum[17] * previous_sum[17] +
previous_sum[18] * previous_sum[18];
previous_sum[0] = 0;
}
else {
sum_counter++;
sum_square_counter += ((n - 1) % 10) * 2 + 1;
}
// get_sum_and_sum_square_digits(n, sum, sum_square);
// assert(sum == sum_counter && sum_square == sum_square_counter);
if (prime_table[sum_counter] && prime_table[sum_square_counter]) {
lucky_counter++;
}
}
return lucky_counter;
}
void inout_lucky_numbers() {
int n;
cin >> n;
long long a;
long long b;
while (n--) {
cin >> a >> b;
cout << count_lucky_number(a, b) << endl;
}
}
int main() {
inout_lucky_numbers();
return 0;
}
答案 0 :(得分:7)
看作A-B可能是10 ^ 18个值的范围,无论多么优化,都无法及时从A循环到B.让我们试着找出一种不需要专门考虑所有这些数字的方法......
首先,让我们减少找到1到E之间的幸运数字的问题,并称之为幸运(E)。总体问题的答案很幸运(B) - 鲁莽(A-1)。
现在让我们逐个数字地构建这样一个幸运数字。假设我们已经在这个数字上放了几个数字,需要继续。我们已经放置了哪些数字是否重要?没有!我们只需知道以下内容:
这将是动态编程中所谓的状态。
让我们忽略10 ^ 18,因为它是输入中唯一一个有19位数的数字而且不幸运。请注意,E最多可以有18位数字,因此我们有n种可能性(从0到18),s(s)可能有162种(18 * 9 + 1),平方可能有1459种(18 * 81 + 1)。给我们留下了最多500万的搜索空间,这比搜索10 ^ 18个匹配的数字要小得多。
因此,让我们将F(n,s,sq)定义为“我们可以通过多少种方式将数字添加到具有此类属性以获得幸运数字的数字”(感谢kilotaras的重新编写)。基本情况是当n等于E中的位数时:如果s和sq为素数,则F(N,s,s_sq)为1,否则为0。对于其他可能性,进行可能的转换并递归调用F,注意不要让你正在构建的数字超过E.
通过这种方式,我们可以将lucky(E)定义为F(0,0,0)。
完成后,请记住为已计算的输入/输出记忆功能。
编辑:这有点旧,但这里是幸运函数的示例实现,我认为是正确的。请注意,代码中的n与上面的解释相反,因为以这种方式编写代码要容易得多。
long long dp[20][163][1460];
bool calc[20][163][1460];
int digits[20];
int digit_cnt;
// The last argument (eq) is used to avoid going over E
long long F(int n, int s, int sq, bool eq) {
// Base cases
if (!eq && calc[n][s][sq]) return dp[n][s][sq];
if (n == 0) return (prime_table[s] && prime_table[sq]);
long long resp = 0;
// Test all possibilities for the next digit
for (int d = 0; d < 10; d++) {
if (!eq || digits[n-1] > d) {
resp += F(n-1, s+d, sq + d*d, false);
}
// If the number formed so far is exactly equal to E
// we will go over E if we pick a larger
// digit than digits[n-1].
// So we have to take care if eq == true
else if (digits[n-1] == d) {
resp += F(n-1, s+d, sq + d*d, true);
}
else break;
}
// Note that computations that have eq set to true
// can't be used in other calculations of F(), as they depend on E.
if (!eq) {
calc[n][s][sq] = true;
dp[n][s][sq] = resp;
}
return resp;
}
long long lucky(long long E) {
long long tE = E;
digit_cnt = 0;
while (tE) {
digits[digit_cnt++] = tE % 10;
tE /= 10;
}
return F(digit_cnt, 0, 0, true);
}
答案 1 :(得分:2)
检查数字是否为素数很容易,您遇到的最高数字是1458(数字999,999,999,999,999,999)。我猜这就是为什么你有prime_table
,这很好。因此,查看特定数字是否为素数不能更快。我认为你肯定应该使用你拥有的prime_table,虽然如果你在程序开始时计算它而不是硬编码会更好 - 错误的可能性更小。
您可以创建其他缓存。你需要遍历所有数字并将它们和它们的正方形相加。但是没有人说你应该逐个查看数字。你可以一次超过5位数 - 你需要的是两个1000000个单元格的数组,一个包含数字之和,一个包含平方和。
因此,你有一个素数数组,一个数字,用于所有6位数的数字之和,以及一个数组,用于表示所有6位数字的数字平方和。获得任何18位数字的解决方案将非常简单 - 您有2个modulu操作,2个分区,4个添加和7个查找。你不可能比这更快。
注意:玩1000000数字。如果你的L1缓存很小,100000可能会更快,虽然我相信1000000你仍然没问题 - 你有大约2MB的数据你一直在访问,这应该适合你的L1缓存。