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*(n-1)/2或n*(n+1)/2形式表示的数为三角形数;

       然后整理得n=6*(sigma((i*(i-1)/2))+x(i*(i-1)为偶数);

       也就是说n%6即为所求结果,当n%6=1,2时特判一下是否能找到满足条件的数;

二分查找:(手动二分)(STL二分)

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int t,n,m,mark;
int num[500010];
void pre()
{
    for(int i=1;i<20000;i++){
       num[i]=3*i*(i-1)+1;
    }
}
/*int seek(int x)
{
    int k=lower_bound(num,num+20000,x)-num;
    return num[k]==x;
}*/
int seek(int x)
{
    int l=0,r=20000;
    while(l<=r)
    {
        int mid=(l+r)/2;
        if(num[mid]==x) return 1;
        else if(num[mid]<x) l=mid+1;
        else if(num[mid]>x) r=mid-1;
    }
    return 0;
}
int main()
{
    int i,j,k,temp;
    pre();
    while(scanf("%d",&t)!=EOF)
    {
        while(t--)
        {
            scanf("%d",&n);
            temp=(n-1)%6+1;
            mark=0;
            if(temp>2) printf("%d\n",temp);
            else{
                if(temp==1){
                    if(seek(n)) printf("1\n");
                    else printf("7\n");
                    continue;
                }
                else{
                    for(i=1;num[i]*2<=n;i++){
                       if(seek(n-num[i])){
                           mark=1;break;
                       }
                    }
                    if(mark) printf("2\n");
                    else printf("8\n");
                }
            }
        }
    }
    return 0;
}

STL中map映射:

#include<cstdio>
#include<cstring>
#include<map>
#include<algorithm>
using namespace std;
int t,n,m,mark;
int num[500010];
map<int,int> mm;
void pre()
{
    for(int i=1;i<20000;i++){
       num[i]=3*i*(i-1)+1;
       mm[num[i]]=i;
    }
}
int main()
{
    int i,j,k,temp;
    pre();
    while(scanf("%d",&t)!=EOF)
    {
        while(t--)
        {
            scanf("%d",&n);
            temp=(n-1)%6+1;
            mark=0;
            if(temp>2) printf("%d\n",temp);
            else{
                if(temp==1){
                    if(mm.count(n)) printf("1\n");
                    else printf("7\n");
                    continue;
                }
                else{
                    for(i=1;num[i]*2<=n;i++){
                       if(mm.count(n-num[i])){
                           mark=1;break;
                       }
                    }
                    if(mark) printf("2\n");
                    else printf("8\n");
                }
            }
        }
    }
    return 0;
}

 

posted on 2015-07-27 09:56  大树置林  阅读(337)  评论(0编辑  收藏  举报

导航