BestCoder 1st Anniversary ($) HDU5312 Sequence

49 篇文章 0 订阅
35 篇文章 0 订阅




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  (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
 

Source




出题人: 这个题看上去是一个贪心, 但是这个贪心显然是错的. 

事实上这道题目很简单, 先判断1 个是否可以, 然后判断2个是否可以.

 之后找到最小的k (k > 2)k(k>2), 使得(m - k) mod 6 = 0(mk)mod6=0即可.

证明如下: 3n(n-1)+1 = 6(n*(n-1)/2)+13n(n1)+1=6(n(n1)/2)+1

注意到n*(n-1)/2n(n1)/2是三角形数, 任意一个自然数最多只需要3个

三角形数即可表示. 枚举需要kk个, 那么显然m=6(km=6(k个三角形数的和)+k)+k

由于k \ge 3k3, 只要m-kmk是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  (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
 

Source




出题人: 这个题看上去是一个贪心, 但是这个贪心显然是错的. 

事实上这道题目很简单, 先判断1 个是否可以, 然后判断2个是否可以.

 之后找到最小的k (k > 2)k(k>2), 使得(m - k) mod 6 = 0(mk)mod6=0即可.

证明如下: 3n(n-1)+1 = 6(n*(n-1)/2)+13n(n1)+1=6(n(n1)/2)+1

注意到n*(n-1)/2n(n1)/2是三角形数, 任意一个自然数最多只需要3个

三角形数即可表示. 枚举需要kk个, 那么显然m=6(km=6(k个三角形数的和)+k)+k

由于k \ge 3k3, 只要m-kmk是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;
}
        
        
       
       
      
      
     
     






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值