题目描述
如果一个素数转换成十六进制后是“对称”的,我们将其称为“十六进制对称素数”,例如17(11H)
就是一个“十六进制对称素数”,而19(13H)
虽然是素数但十六进制并不“对称”。
试统计在[n,m]
范围内有多少素数是“十六进制对称素数”。
输入
两个整数n和m
输出
范围内“十六进制对称素数”的个数
样例输入
10 20
样例输出
3
提示
1
<
n
<
m
<
2
32
1<n<m<2^{32}
1<n<m<232
样例说明:[10,20]
之间的素数有11(BH)
,13(DH)
,17(11H)
,19(13H)
,其中11
,13
,17
是“十六进制对称素数”
思路
通过dfs不断生成(或者也可以称为搜索)十六进制对称数,并进行判断是否为素数。素数的判断利用了“大于5的质数一定和6的倍数相邻”的性质,相比于朴素试除法节约 2 3 \frac{2}{3} 32的时间。
AC代码
#include <bits/stdc++.h>
using namespace std;
long long hx[10] = {0, 1, 16, 256, 4096, 65536, 1048576, 16777216, 268435456, 4294967296};
int n, m, res;
bool prime(long long num) {
if (num == 2 || num == 3) return 1;
if (num % 6 != 1 && num % 6 != 5) return 0;
for (int i = 5; i <= floor(sqrt(num)); i += 6)
if (num % i == 0 || num % (i + 2) == 0) return 0;
return 1;
}
void dfs(int k, int bit, long long sum) {
if (k > ceil(bit * 1.0 / 2)) {
if (sum > m) {
cout << res;
exit(0);
} else if (sum >= n && prime(sum)) ++res;
return;
}
for (int i = k == 1 ? 1 : 0; i <= 15; i++) {
dfs(k + 1, bit, sum + ((k != bit - k + 1) ? i * hx[k] + i * hx[bit - k + 1] : i * hx[k]));
}
}
int main() {
int cnt = 0;
cin >> n >> m;
int tmp = n;
while (tmp) {
tmp /= 16;
++cnt;
}
while (cnt) {
dfs(1, cnt, 0);
++cnt;
}
return 0;
}