• hdu 5312 Sequence


    问题描述
    Soda习得了一个数列, 数列的第n(n≥1)项是3n(n-1)+1. 现在他想知道对于一个给定的整数m, 是否可以表示成若干项上述数列的和. 如果可以, 那么需要的最小项数是多少?
     
    例如, 22可以表示为7+7+7+1, 也可以表示为19+1+1+1
    输入描述
    输入有多组数据. 第一行有一个整数T(1≤T≤104 ), 表示测试数据组数. 然后对于每组数据:
     
    一行包含1个整数 m(1≤m≤109).
    输出描述
    对于每组数据输出最小花费.
    输入样例
    10
    1
    2
    3
    4
    5
    6
    7
    8
    22
    10
    输出样例
    1
    2
    3
    4
    5
    6
    1
    2
    4
    4
     

    对于这种题,首先一开始就要对给出的公式进行研究,从这里入手是正道。

    分析公式 3n(n−1)+1 ,若给出一个数n,假设要k个3n(n−1)+1加起来得到n,即 3n(n-1)k+k=n,注意到3n(n-1)k是6的倍数,那么求的是满足(n-k)%6==0的最小的k。还有就是要注意到1、2要特判,即k要从3开始枚举

    打表发现规律了就好做了、 当n%6==1 时要考虑能否由1个数组成在表中找到就可以 否则就需要7项的和了(规律跑个程序或者列举一些数就发现了)

    当n%6==2时 要考虑能否由2个数组成 根据表中数据列举一些数(跑个程序更快更简洁)会发现只有2和8两种情况

    剩下的就注意一下是6的倍数的直接输出6否则输出n%6即可

     /*附上渣渣程序
    #include<stdio.h>
    int main()
    {
        int i, j;
        for(i = 7; i <= 100; i++)
        {
            for(j = 1; j < 10; j++)
            {
                  if((i-j) % 6 == 0 && i != j && i%6==1)
                      printf("%d %d ", i, j);
            }
        }
           for(i = 7; i <= 100; i++)
        {
            for(j = 1; j < 10; j++)
            {
                  if((i-j) % 6 == 0 && i != j && i%6==2)
                      printf("%d %d ", i, j);
            }
        }
        return 0;
    }
    */

    #include<cstdio>
    #include<cstring>
    #include<stack>
    #include<vector>
    #include<queue>
    #include<cmath>
    #include<cstdlib>
    #include<algorithm>
    using namespace std;
    const int oo = 0x3f3f3f3f;
    const int maxn = 1e6+7;
    const int mod = 1e9+7;
    int Soda[maxn]={1}, id;///id为最后一个数的下标
    void init()///打表
    {
        for(int i=1; i<=20000; i++)
        {
            Soda[i]=3*i*(i-1)+1;
            if(Soda[i] >= mod-7) {id = i; break;}
        }
    }
    int Search(int left, int right, int x)///二分查找
    {
        int mid = (left+right)/2;
    
        if(Soda[mid] == x) return 1;
    
        if(left > right) return 0;
    
        if(Soda[mid] < x) return Search(mid+1, right, x);
    
        else return Search(left, mid-1, x);
    }
    int main()
    {
        init();///打表
        int T, i, n, ans;
      //  for(i = 0; i < 20; i++)
       //     printf("%d
    ", Soda[i]);
        scanf("%d", &T);
        while(T--)
        {
            scanf("%d", &n);
            if(n%6==1)
            {
                if(Search(0, id, n)) ans = 1;
                else ans = 7;
            }
            else if(n%6==2)
            {
                int ok = 0, p = id;
                for(i = 1; i <= p; i++)
                {
                    while(Soda[i] + Soda[p] > n)
                        p--;
                    if(Soda[i]+Soda[p] == n)
                    {
                        ok = 1;
                        break;
                    }
                }
                if(ok) ans = 2;
                else ans = 8;
            }
            else
            {
                ans = n%6;
                if(ans == 0) ans = 6;
             // ans = (n-1)%6+1;
            }
            printf("%d
    ", ans);
        }
        return 0;
    }
    
  • 相关阅读:
    【Linux开发】Linux下jpeglib库的安装详解
    【Linux开发】Linux下jpeglib库的安装详解
    【Linux开发】jpeglib使用指南
    【Linux开发】jpeglib使用指南
    【Linux开发】为qt-embedded添加jpeg库的交叉编译方法for arm
    【Linux开发】为qt-embedded添加jpeg库的交叉编译方法for arm
    Windows 7 64bit上安装Oracle Database 12c [INS-30131] 错误的解决方法
    Log4j 日志记录
    如何根据Ip获取地址信息--Java----待整理完善!!!
    Struts如何获取客户端ip地址
  • 原文地址:https://www.cnblogs.com/PersistFaith/p/4962494.html
Copyright © 2020-2023  润新知