HDU--5312(规律+数学)

思路:这个题看上去是一个贪心, 但是这个贪心显然是错的. 事实上这道题目很简单, 先判断1个是否可以, 然后判断2个是否可以. 之后找到最小的k
(k > 2)k(k>2),
使得(m - k) mod 6 =
0(m?k)mod6=0即可.

证明如下: 3n(n-1)+1 =
6(n*(n-1)/2)+13n(n?1)+1=6(n?(n?1)/2)+1,
注意到n*(n-1)/2n?(n?1)/2是三角形数,
任意一个自然数最多只需要3个三角形数即可表示. 枚举需要kk个,
那么显然m=6(km=6(k个三角形数的和)+k)+k,
由于k \ge 3k≥3,
只要m-km?k是6的倍数就一定是有解的.

事实上, 打个表应该也能发现规律.

两边向中间找扫描的时候落了等号错了好多次,忘了数相等的时候也可以,最后找最小的k,直接取余就行,最少是从3开始的。

#include <bits/stdc++.h>
#pragma comment(linker, "/STACK:1024000000,1024000000")
#define INF 9999999999
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef unsigned long long llu;
typedef long long ll;
const int maxd=18258+5;
///=========================
int s[maxd];
int m;
void table()
{
    s[0]=0;
    for(int i=1;i<maxd;i++)
        s[i]=3*i*(i-1)+1;
}

bool ok1(int x)
{
    int pos=lower_bound(s,s+maxd,x)-s;
    if(s[pos]==x) return true;
    return false;
}

bool ok2(int x)
{
    if((x-2)%6) return false;
    int l=1,r=maxd-1;
    while(l<=r)
    {
        if(s[l]+s[r]<x)
            l++;
        else if(s[l]+s[r]>x)
            r--;
        else return true;
    }
    return false;
}

int main()
{
    int kase;
    // freopen("1.txt","r",stdin);
    table();
    scanf("%d",&kase);
    while(kase--)
    {
        scanf("%d",&m);
        if(ok1(m))
            printf("1\n");
        else if(ok2(m))
            printf("2\n");
        else
        {
//            for(int k=3;k<=m;k++)
//                if((m-k)%6==0)
//            {
//                printf("%d\n",k);
//                break;
//            }
           printf("%d\n",(m-3)%6+3);
        }
    }
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-10 06:10:41

HDU--5312(规律+数学)的相关文章

hdu 5312 Sequence(数学思维)

题意:通式为3*i*(i-1)+1(n>=1)的数列中每个数可用若干次,求构成给定n所需的最小个数: 思路: 设构成n所需个数为x,则n=3*1*(1-1)+3*2*(2-1)+...+3*x*(x-1)+x;当时推到这一步就没有再做下去了: 然后整理得n=6*(sigma((i*(i-1)/2))+x(i*(i-1)为偶数); 也就是说n%6即为所求结果,当n%6=1,2时特判一下是否能找到满足条件的数: 二分查找:(手动二分)(STL二分) #include<cstdio> #inc

hdu1466 计算直线的交点数(找规律+数学)

转载请注明出处:http://blog.csdn.net/u012860063?viewmode=contents 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1466 计算直线的交点数 Problem Description 平面上有n条直线,且无三线共点,问这些直线能有多少种不同交点数. 比如,如果n=2,则可能的交点数量为0(平行)或者1(不平行). Input 输入数据包含多个测试实例,每个测试实例占一行,每行包含一个正整数n(n<=20

hdu 4811 Ball(数学)

题目链接:hdu 4811 Ball 题目大意:有三种颜色的球若干,每次向桌子上放一个球,保证是一条序列,每次放球的得分为当前放入序列的球的前面有多少种不同的颜色a,后面的有多少种不同的颜色b,a+b.问说给定球的数量后,最大得分为多少. 解题思路:因为放球顺序是自己定的,所以我们可以尽量早得构造一个序列,使得后面放入球的得分均保持在峰值.那么求峰值就要根据球的数量来决定.我们叫得分为峰值的求为最高得分球,它们有很多个.对于一种颜色来说:0个,表示不能为在最高得分球的左边和右边,换句话来说,就是

hdu 5312 Sequence【数学推导】

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5312 解法: 这个题看上去是一个贪心, 但是这个贪心显然是错的. 事实上这道题目很简单, 先判断1个是否可以, 然后判断2个是否可以. 之后找到最小的整数k (k > 2), 使得(m - k) mod 6 = 0即可. 证明如下: 3n(n-1)+1 = 6(n*(n-1)/2)+1, 注意到n*(n-1)/2是三角形数, 任意一个自然数最多只需要3个三角形数即可表示. 枚举需要k个. 事实上,

hdu 5312 Sequence(数学推导——三角形数)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5312 Sequence Time Limit: 2000/2000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) Total Submission(s): 1336    Accepted Submission(s): 410 Problem Description Today, Soda has learned a

【HDU 5312】Sequence(数学问题)

这个题看上去是一个贪心, 但是这个贪心显然是错的. 事实上这道题目很简单, 先判断1个是否可以, 然后判断2个是否可以. 之后找到最小的k (k > 2)k(k>2), 使得(m - k) mod 6 = 0(m?k)mod6=0即可. 证明如下: 3n(n-1)+1 = 6(n*(n-1)/2)+13n(n?1)+1=6(n?(n?1)/2)+1, 注意到n*(n-1)/2n?(n?1)/2是三角形数, 任意一个自然数最多只需要3个三角形数即可表示. 枚举需要kk个, 那么显然m=6(km=

hdu 5312 数学

HDU 5312 Sequence (规律题)

题意:一个序列的第n项为3*n*(n-1)+1,而 n>=1,现在给一个正整数m,问其最少由多少个序列中的数组成? 思路:首先,序列第1项是1,所以任何数都能构成了.但是最少应该是多少?对式子进行变形,6*(n*(n-1)/2)+1,看到了三角形数n*(n-1)/2,那么应该是6*(任意自然数)+x=m才对,因为最多只要3个三角形数就能组成任何自然数啦. 不妨试试m%6是多少?这样试图求x可以吗?因为任意自然数最多由3个组成,如果是k个,那么应该x>=k,别忘了还有个+1的项.x-k那部分,就

hdu 5312 Sequence(数学推导+线性探查(两数相加版))

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,

HDU 5312(数学推导+技巧)

首先说一下.N*(N-1)/2为三角形数,随意一个自然数都最多可由三个三角形数表示. 对于,对于给定的要求值 V, 那么其一组解可表示为 V = 6*(K个三角形数的和)+K: 即随意由k个数组成的解 都有 (V-K)%6==0; 那么仅仅须要找到最小的K(1,2须要特判,结论最小值为3): 在对2进行特判时候,能够从两端到中间的线性扫描来做. #include <cstdio> #include <cstring> #include <algorithm> #incl