hdu 5312 三角形数 二分查找

Sequence

Time Limit: 2000/2000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)

Total Submission(s): 891    Accepted Submission(s): 271

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.

Input

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

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

题意,给出一个数列3n(n?1)+1,再给一个任意一个数m,要求最少能用多少个数列中的数之和为m

给出一个规律:n*(n-1)/2是三角形数,任何一个自然数可用最多三个三角形数拼成,这个规律得知道,才可以解出这题。

把上式变形得到6*(n * (n-1)/2) + 1;如果,m是由k个数组成,那m不就可以表示成6 * (k个三角形数之和) + k这样的形式了。k个三角形数之和,如果k>

=3,那么,由上面的规律,我们可以马上知道,这样的数肯定是存在的。k = 1 k = 2,要分开讨论。k = 1时,只需要二分找出是数列中的一个数就可以了。

k = 2时,找出 pri[i] + pri[j] = m(pri是给出的数列),这样的i,j是否存在, 一种方法,枚举i,得到m - pri[i] 判定是否在pri中,这样的复杂度是o(n * log(n)),

n是这个数列的个数。显然复杂度太高,我们知道,pri这个数列是递增的,我们可以用这个性质,i = 0 ,j = prilen -1;如果pri[i] + pri[j] > m;j--;否则i++;这

样,一定可以找出来是否和为m且复杂度只能o(n),这样才能过这题。由于i 只会加n次,j也只会减n次,所以总的复杂度为o(N)

为什么这样是对的呢,其实很简单,假设pri[ii]  + pri[jj] = m,这样的方法,会不会,没找到ii,jj呢,不会,

初始 i < ii j>jj;如果pri[i] + pri[j] < m i++,否则j--,

1.假如,i先到达ii,此时,j > jj,pri[i] + pri[j] > pri[ii] + pri[jj] = m ;所以j--,最终一定会是,j = jj;

2.假如,j先到达jj,此时,i < ii,pri[i] + pri[j] < pri[ii] + pri[jj] = m ;所以i++,最终一定会是,i = ii;

所以不管怎么样,一定会找到答案。

#define N 205
#define M 100005
#define maxn 205
#define MOD 1000000000
int n,glen,len,pn,m,pri[M];
set<int> myset;
set<int>::iterator it;
bool solve1(int mm){
    return myset.count(mm);
}
bool solve2(int mm){
    for(int i = 0,j = pn -1;i< pn && pri[i] <= mm;i++){
        while(j>= 0 && pri[i] + pri[j] > mm)j--;
        if(j>=0 && pri[i] + pri[j] == mm) return true;
    }
    return false;
}
int main()
{
    pn = 0;
    for(int i = 1;i< M -1 ;i++){
        int t = 3 * i * (i-1) + 1;
        if(t <= MOD){
            pri[pn++] = t;
            myset.insert(t);
        }
        else break;
    }
    while(S(n)!=EOF)
    {
        while(n--){
            S(m);
            if(m%6 == 1){
                if(solve1(m))
                    printf("1\n");
                else
                    printf("7\n");
                continue;
            }
            else if(m%6 == 2)
            {
                if(solve2(m))
                    printf("2\n");
                else
                    printf("8\n");
                continue;
            }
            else
                printf("%d\n",(m - 1)%6 + 1);
        }
    }
    return 0;
}

Source

BestCoder 1st Anniversary ($)

Recommend

hujie   |   We have carefully selected several similar problems for you:  5315 5314 5310 5309 5308

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

时间: 2024-10-11 01:20:40

hdu 5312 三角形数 二分查找的相关文章

hdu 4768 Flyer(二分查找)

Flyer Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1537    Accepted Submission(s): 552 Problem Description The new semester begins! Different kinds of student societies are all trying to adv

hdu 5249 KPI 【二分查找】

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5249 分析:这道题是2015百度之星初赛1的4题 这道题不算太难当时队友做出来了,不过费了老大劲,其实我从中能够吸取教训的, 原因是,我一看这道题就是数据结构的,然后和队友想的一样二分查找,但是从中 遇到了一系列的问题: 首先储存数据我们不能用带有下标的数组,因为题目中的数据是可删可添的这样如果用 数组的话时间复杂度是相当高的,因为如果按大小插入,就要移动其他数据,如果在 尾部添加,就要对其排序,因

HDU 5312-Sequence(三角形数+推导)

题目地址:HDU 5312 题意:Soda习得了一个数列, 数列的第nn (n \ge 1)(n≥1)项是3n(n-1)+13n(n?1)+1. 现在他想知道对于一个给定的整数mm, 是否可以表示成若干项上述数列的和. 如果可以, 那么需要的最小项数是多少?例如, 22可以表示为7+7+7+17+7+7+1, 也可以表示为19+1+1+119+1+1+1. 思路: 三角形数形如n*(n-1)/2,他们形成的数列是1,3,6,10.......,同样也可以表示成n*(n+1)/2(表示方式不同).

HDU 3763 CD【二分查找】

解题思路:给出两个数列an,bn,求an和bn中相同元素的个数因为注意到n的取值是0到1000000,所以可以用二分查找来做,因为题目中给出的an,bn,已经是单调递增的,所以不用排序了,对于输入的每一个b[i],查找它在an数列中是否存在.存在返回值为1,不存在返回值为0 CD Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 627

hdu 1969 Pie(贪心+二分查找)(简单)

Pie Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 5628    Accepted Submission(s): 2184 Problem Description My birthday is coming up and traditionally I'm serving pie. Not just one pie, no, I

hdu 1969 Pie(二分查找)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1969 Pie Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 4513    Accepted Submission(s): 1819 Problem Description My birthday is coming up and trad

养成良好的编程风格--论二分查找的正确姿势

摘自:http://www.cnblogs.com/ider/archive/2012/04/01/binary_search.html 在学习算法的过程中,我们除了要了解某个算法的基本原理.实现方式,更重要的一个环节是利用big-O理论来分析算法的复杂度.在时间复杂度和空间复杂度之间,我们又会更注重时间复杂度. 时间复杂度按优劣排差不多集中在: O(1), O(log n), O(n), O(n log n), O(n2), O(nk), O(2n) 到目前位置,似乎我学到的算法中,时间复杂度

二分查找的实现和应用汇总(转载)

转载地址:http://www.cnblogs.com/ider/archive/2012/04/01/binary_search.html 二分查找法的实现和应用汇总 在学习算法的过程中,我们除了要了解某个算法的基本原理.实现方式,更重要的一个环节是利用big-O理论来分析算法的复杂度.在时间复杂度和空间复杂度之间,我们又会更注重时间复杂度. 时间复杂度按优劣排差不多集中在: O(1), O(log n), O(n), O(n log n), O(n2), O(nk), O(2n) 到目前位置

【转载】二分查找

[本文转自]http://www.cnblogs.com/ider/archive/2012/04/01/binary_search.html 在学习算法的过程中,我们除了要了解某个算法的基本原理.实现方式,更重要的一个环节是利用big-O理论来分析算法的复杂度.在时间复杂度和空间复杂度之间,我们又会更注重时间复杂度. 时间复杂度按优劣排差不多集中在: O(1), O(log n), O(n), O(n log n), O(n2), O(nk), O(2n) 到目前位置,似乎我学到的算法中,时间