题目传送门
1 /*
2 官方题解:
3 这个题看上去是一个贪心, 但是这个贪心显然是错的.
4 事实上这道题目很简单, 先判断1个是否可以, 然后判断2个是否可以. 之后找到最小的k(k>2), 使得(m-k)mod6=0即可.
5 证明如下:
6 3n(n-1)+1=6(n*(n-1)/2)+1, 注意到n*(n-1)/2是三角形数, 任意一个自然数最多只需要3个三角形数即可表示.
7 枚举需要k个, 那么显然m=6(k个三角形数的和)+k, 由于k≥3, 只要m?k是6的倍数就一定是有解的.
8 事实上, 打个表应该也能发现规律.
9 */
10 #include <cstdio>
11 #include <algorithm>
12 #include <cmath>
13 #include <cstring>
14 using namespace std;
15
16 typedef long long ll;
17 const int MAXN = 2e4 + 10;
18 const int INF = 0x3f3f3f3f;
19 ll a[MAXN];
20 int tot;
21
22 void solve(void) {
23 for (ll i=1; i<=20000; ++i) {
24 a[i] = (ll) 3 * i * (i - 1) + 1;
25 if (a[i] > (ll) 1000000000) return ;
26 tot = i;
27 }
28 }
29
30 bool ok(ll m) {
31 int j = tot;
32 for (int i=1; i<=tot; ++i) {
33 while (a[i] + a[j] > m) j--;
34 if (j >=1 && a[i] + a[j] == m) return true;
35 }
36 return false;
37 }
38
39 int main(void) { //BestCoder 1st Anniversary($) 1003 Sequence
40 //freopen ("C.in", "r", stdin);
41 tot = 0; solve ();
42 int T; scanf ("%d", &T);
43 while (T--) {
44 ll m; scanf ("%I64d", &m);
45 if (m % 6 == 0) puts ("6");
46 else if (m % 6 == 1) {
47 if (*lower_bound (a+1, a+1+tot, m) == m) puts ("1");
48 else puts ("7");
49 }
50 else if (m % 6 == 2) {
51 if (ok (m)) puts ("2");
52 else puts ("8");
53 }
54 else printf ("%d
", m % 6);
55 }
56
57 return 0;
58 }