
正文
BestCoder 1st Anniversary($) 1003 Sequence
提示:扫一扫查出行【扫一扫了解最新限行尾号】
复制提示
题目传送门
/*
官方题解:
这个题看上去是一个贪心, 但是这个贪心显然是错的.
事实上这道题目很简单, 先判断1个是否可以, 然后判断2个是否可以. 之后找到最小的k(k>2), 使得(m-k)mod6=0即可.
证明如下:
3n(n-1)+1=6(n*(n-1)/2)+1, 注意到n*(n-1)/2是三角形数, 任意一个自然数最多只需要3个三角形数即可表示.
枚举需要k个, 那么显然m=6(k个三角形数的和)+k, 由于k≥3, 只要m?k是6的倍数就一定是有解的.
事实上, 打个表应该也能发现规律.
*/
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
using namespace std; typedef long long ll;
const int MAXN = 2e4 + ;
const int INF = 0x3f3f3f3f;
ll a[MAXN];
int tot; void solve(void) {
for (ll i=; i<=; ++i) {
a[i] = (ll) * i * (i - ) + ;
if (a[i] > (ll) ) return ;
tot = i;
}
} bool ok(ll m) {
int j = tot;
for (int i=; i<=tot; ++i) {
while (a[i] + a[j] > m) j--;
if (j >= && a[i] + a[j] == m) return true;
}
return false;
} int main(void) { //BestCoder 1st Anniversary($) 1003 Sequence
//freopen ("C.in", "r", stdin);
tot = ; solve ();
int T; scanf ("%d", &T);
while (T--) {
ll m; scanf ("%I64d", &m);
if (m % == ) puts ("");
else if (m % == ) {
if (*lower_bound (a+, a++tot, m) == m) puts ("");
else puts ("");
}
else if (m % == ) {
if (ok (m)) puts ("");
else puts ("");
}
else printf ("%d\n", m % );
} return ;
}






