Sequence
Time Limit: 2000/2000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)Total Submission(s): 1296 Accepted Submission(s): 398
Problem Description
Today, Soda has learned a sequence whose
n-th
(n≥1)
item is
3n(n−1)+1
. Now he wants to know if an integer
m can be represented as the sum of some items of that sequence. If possible, what are the minimum items needed?
For example, 22=19+1+1+1=7+7+7+1 .
For example, 22=19+1+1+1=7+7+7+1 .
Input
There are multiple test cases. The first line of input contains an integer
T
(1≤T≤104)
, indicating the number of test cases. For each test case:
There's a line containing an integer m (1≤m≤109) .
There's a line containing an integer m (1≤m≤109) .
Output
For each test case, output
−1
if
m cannot be represented as the sum of some items of that sequence, otherwise output the minimum items needed.
Sample Input
10 1 2 3 4 5 6 7 8 22 10
Sample Output
1 2 3 4 5 6 1 2 4 4
Source
出题人:
这个题看上去是一个贪心, 但是这个贪心显然是错的.
事实上这道题目很简单, 先判断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
#include
#include
#include
using namespace std;
typedef long long ll;
const int MAXN = 2e4 + 10;
const int INF = 0x3f3f3f3f;
ll a[MAXN];
int tot;
void solve(void) {
for (ll i=1; i<=18258; ++i) {
a[i] = (ll) 3 * i * (i - 1) + 1;
tot = i;
}
return ;
}
bool ok(ll m) {
int j = tot;
for (int i=1; i<=tot; ++i) {
while (a[i] + a[j] > m) j--;
if (j >=1 && a[i] + a[j] == m) return true;
}
return false;
}
int main(void) { //BestCoder 1st Anniversary($) 1003 Sequence
//freopen ("C.in", "r", stdin);
tot = 0; solve ();
int T; scanf ("%d", &T);
while (T--) {
ll m; scanf ("%I64d", &m);
if (m % 6 == 0) puts ("6");
else if (m % 6 == 1) {
if (*lower_bound (a+1, a+1+tot, m) == m) puts ("1");
else puts ("7");
}
else if (m % 6 == 2) {
if (ok (m)) puts ("2");
else puts ("8");
}
else printf ("%d\n", m % 6);
}
return 0;
}
1003:HDU5312 Sequence
Sequence
Time Limit: 2000/2000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)Total Submission(s): 1296 Accepted Submission(s): 398
Problem Description
Today, Soda has learned a sequence whose
n-th
(n≥1)
item is
3n(n−1)+1
. Now he wants to know if an integer
m can be represented as the sum of some items of that sequence. If possible, what are the minimum items needed?
For example, 22=19+1+1+1=7+7+7+1 .
For example, 22=19+1+1+1=7+7+7+1 .
Input
There are multiple test cases. The first line of input contains an integer
T
(1≤T≤104)
, indicating the number of test cases. For each test case:
There's a line containing an integer m (1≤m≤109) .
There's a line containing an integer m (1≤m≤109) .
Output
For each test case, output
−1
if
m cannot be represented as the sum of some items of that sequence, otherwise output the minimum items needed.
Sample Input
10 1 2 3 4 5 6 7 8 22 10
Sample Output
1 2 3 4 5 6 1 2 4 4
Source
出题人:
这个题看上去是一个贪心, 但是这个贪心显然是错的.
事实上这道题目很简单, 先判断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
#include
#include
#include
using namespace std;
typedef long long ll;
const int MAXN = 2e4 + 10;
const int INF = 0x3f3f3f3f;
ll a[MAXN];
int tot;
void solve(void) {
for (ll i=1; i<=18258; ++i) {
a[i] = (ll) 3 * i * (i - 1) + 1;
tot = i;
}
return ;
}
bool ok(ll m) {
int j = tot;
for (int i=1; i<=tot; ++i) {
while (a[i] + a[j] > m) j--;
if (j >=1 && a[i] + a[j] == m) return true;
}
return false;
}
int main(void) { //BestCoder 1st Anniversary($) 1003 Sequence
//freopen ("C.in", "r", stdin);
tot = 0; solve ();
int T; scanf ("%d", &T);
while (T--) {
ll m; scanf ("%I64d", &m);
if (m % 6 == 0) puts ("6");
else if (m % 6 == 1) {
if (*lower_bound (a+1, a+1+tot, m) == m) puts ("1");
else puts ("7");
}
else if (m % 6 == 2) {
if (ok (m)) puts ("2");
else puts ("8");
}
else printf ("%d\n", m % 6);
}
return 0;
}