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\n", m % 6); 55 } 56 57 return 0; 58 }
时间: 2024-10-25 13:49:41