HDU 5312 Sequence(三角形数应用)——BestCoder 1st Anniversary ($)

227 篇文章 0 订阅
97 篇文章 0 订阅

传送门

Sequence

Time Limit: 2000/2000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 1424    Accepted Submission(s): 442


Problem Description
Today, Soda has learned a sequence whose n -th (n1) item is 3n(n1)+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.
 

Input
There are multiple test cases. The first line of input contains an integer T (1T104), indicating the number of test cases. For each test case:

There’s a line containing an integer m (1m109).
 

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
 


题目大意:

通式为 3i(i1)+1(i>=1) 的数列中每个数可用多次,然后给你一个数 m

让你求 这个数列构成 m 的最小项数。

解题思路:

首先将这个式子进行变形,变为 6n(n1)2+1 ,那么我们发现 n(n1)2 是三角形数。

然后我们又知道三角形数可以构成任何数,那么假设题目中给定的 m 是由 k 个数列中

的数组成的就有:

6(k)+k==m

那么我们需要特判 k=1  k=2 的情况,最后跑一个循环判断 mk 是不是 6 的倍

数就行了。

My Code

/**
2016 - 08 - 23 下午
Author: ITAK

Motto:

今日的我要超越昨日的我,明日的我要胜过今日的我,
以创作出更好的代码为目标,不断地超越自己。
**/

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <queue>
#include <algorithm>
#include <set>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
const LL INF = 1e9+5;
const LL MAXN = 1e6+5;
const LL MOD = 1e9+7;
const double eps = 1e-7;
const double PI = acos(-1);
using namespace std;
LL Scan_LL()///输入外挂
{
    LL res=0,ch,flag=0;
    if((ch=getchar())=='-')
        flag=1;
    else if(ch>='0'&&ch<='9')
        res=ch-'0';
    while((ch=getchar())>='0'&&ch<='9')
        res=res*10+ch-'0';
    return flag?-res:res;
}

void Out(LL a)///输出外挂
{
    if(a>9)
        Out(a/10);
    putchar(a%10+'0');
}
LL cnt;
LL a[MAXN], sum[MAXN];
void Init()
{
    a[0] = 1LL, sum[0] = 1LL;
    a[1] = 1LL, sum[1] = 1LL;
    for(LL i=2; i<MAXN; i++)
    {
        a[i] = 3LL*(LL)i*(LL)(i-1)+1LL;
        if(a[i] > INF)
        {
            cnt = i;
            break;
        }
    }
}
bool Judge(LL m)
{
    LL l = 0, r = cnt;
    while(l <= r)
    {
        if(a[l] + a[r] == m)
            return 1;
        else if(a[l] + a[r] < m)
            l++;
        else
            r--;
    }
    return 0;
}
int main()
{
    Init();
    LL T, m;
    T = Scan_LL();
    while(T--)
    {
        m = Scan_LL();
        LL tmp1 = lower_bound(a+1, a+cnt+1, m) - a;
        if(a[tmp1] == m)
        {
            puts("1");
            continue;
        }
        if(Judge(m))
        {
            puts("2");
            continue;
        }
        for(LL i=3; ; i++)
        {
            if( (m-i) % 6 == 0)
            {
                printf("%I64d\n",i);
                break;
            }
        }
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值