首先可以知道这是等差数列,可以用 na1+n×(n−1)/2 快速算出每一个值,
但是如果枚举a1和n的话时间复杂度太高,可以先打表找思路,打表程序如下:
#include<iostream>
#include<cstring>
#include<algorithm>
#include<set>
using namespace std;
const int N = 100010;
typedef long long LL;
int n;
set<LL> a;
int main()
{
scanf("%d", &n);
int idx = 0;
for (int i = 1; i <= n; i++) {
for (int j = 2; j <= n; j++) {
a.insert(j * i + (j * (j - 1ll)) / 2);
}
}
for (set<LL>::iterator it = a.begin(); it != a.end(); it++) cout << *it << ' ';
cout << endl;
// printf("%lld\n", ans);
return 0;
}
输入n = 10发现:1, 2, 4, 8, 16, 32...
,即2n(n=0,1,2…)的数都不“蕴含诗意”。
10
3 5 6 7 9 10 11 12 13 14 15 17 18 19 20 21 22 24 25 26 27 28 30 33 34 35 36 38 39 40 42 44 45 46 49 50 51 52 54 55 56 57 60 63 65 68 69 70 72 75 76 77 81 84 85 90 91 92 95 99 100 105 108 115 117 125 126 135 145
预处理1−1016的数据,用哈希表存储
时间复杂度:O(N)
#include<iostream>
#include<cstring>
#include<algorithm>
#include<unordered_map>
using namespace std;
typedef long long LL;
const LL N = 1e16;
int n;
unordered_map<LL, int> a;
void init()
{
LL t = 1;
while(t < N) {
a[t]++;
t *= 2;
}
}
int main()
{
init();
scanf("%d", &n);
int ans = 0;
for (int i = 0; i < n; i++) {
LL t;
scanf("%lld", &t);
if (a[t] == 1) {
ans++;
}
}
printf("%d", ans);
return 0;
}
🦬