HDU 1085(暴力;找规律;树状数组;母函数)

题意:如题。

解法:这道题目可以用4种方法来解,我使用的是找规律,其它方法有的来自网上,有的来自队友的思路。

 

暴力法:

#include<iostream>
using namespace std;
int main()
{
    int ma[8002];
    int i,j,k,a,b,c;

    while(scanf("%d%d%d",&a,&b,&c),a+b+c)
    {
        memset(ma,0,sizeof(ma));
        for(i=0;i<=a;i++)
        {
            for(j=0;j<=b;j++)
            {
                for(k=0;k<=c;k++)
                {
                    ma[i+j*2+k*5]=1;
                }
            }
        }
        for(i=1;i<=a+b*2+c*5+1;i++)
        {
            if(ma[i]==0)
            {
                printf("%d\n",i);
                break;
            }
        }
    }
    return 0;
}


找规律:

#include <cstdio>
#include <cstring>

#define f(res) printf("%d\n", res)

int main()
{
    int a, b, c;
    while (scanf("%d%d%d", &a, &b, &c))
    {
        if (!(a|b|c)) break;
        if (!a) f(1);
        else if (a < 4 && !b) f(a+1);
        else if (a == 1 && b == 1) f(4);
        else f(a+2*b+5*c+1);
    }
    return 0;
}

 

树状数组:

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
#define Max 10000
int val[35],sum[35],k,tree[Max],t;
bool vis[35],visit[Max];
int lowbit(int x)
{return x&(-x);}
void Add(int pos,int c,int n)
{
    int i;
    for(i=pos;i<=n;i+=lowbit(i))
        tree[i]+=c;
}
int Sum(int pos)
{
    int i,ans=0;
    for(i=pos;i>0;i-=lowbit(i))
        ans+=tree[i];
    return ans;
}
void bit2(int n,int p)
{
    int tmp=1;
    while(n>=tmp)
    {
        val[++k]=tmp*p;
        n-=tmp;
        tmp<<=1;
    }
    if(n*p)
        val[++k]=n*p;
}
void dfs(int now,int pos,int cnt,int n)
{
    if(cnt==n)
    {
        if(!visit[now])
        {
            t++;
            visit[now]=true;
            Add(now,now,sum[k]);
        }
        return ;
    }
    for(int i=pos+1;i<=k;i++)
    {
        if(!vis[i])
        {
            vis[i]=true;
            dfs(now+val[i],i,cnt+1,n);
            vis[i]=false;
        }
    }
    return ;
}
int main()
{
    int i,a,b,c,ans;
    bool flag;
    while(scanf("%d%d%d",&a,&b,&c),a+b+c)
    {
        k=ans=t=0;
        flag=false;
        memset(sum,0,sizeof(sum));
        memset(visit,false,sizeof(visit));
        memset(tree,0,sizeof(tree));
        bit2(a,1);
        bit2(b,2);
        bit2(c,5);
        sort(val+1,val+1+k);
        for(i=1;i<=k;i++)
            sum[i]=sum[i-1]+val[i];
        for(i=1;i<=k;i++)
        {
            memset(vis,false,sizeof(vis));
            dfs(0,0,0,i);
            if(i==7)
                break;
            if(Sum(sum[i])!=(1+sum[i])*sum[i]/2)
            {
                flag=true;
                break;
            }
        }
        if(flag)
        {
            int l=1;int r=sum[i];
            while(r>=l)
            {
                int m=(l+r)>>1;
                if((1+m)*m/2==Sum(m))
                    l=m+1;
                else
                {
                    ans=m;
                    r=m-1;
                }
            }
        }
        else
            ans=a+b*2+c*5+1;
        printf("%d\n",ans);
    }
    return 0;
}

 

母函数:

#include<stdio.h>
#include<string.h>
int main()
{
    int n1,n2,n3,a[3],b[3]={1,2,5};
    int i,j,k,c1[10001],c2[10001],sum;
    while(scanf("%d%d%d",&n1,&n2,&n3),n1||n2||n3)
    {
        sum=n1+2*n2+5*n3;
        a[0]=n1;a[1]=n2;a[2]=n3;
        memset(c1,0,sizeof(c1));
        memset(c2,0,sizeof(c2));
        c1[0]=1;
        for(i=0;i<3;i++)
        {
            for(j=0;j<=sum;j++)
            if(c1[j])
            for(k=0;j+k<=sum&&k<=b[i]*a[i];k+=b[i])
            c2[k+j]+=c1[j];
            for(j=0;j<=sum;j++)
            {c1[j]=c2[j];c2[j]=0;}
        }
        for(i=0;i<=sum;i++)
            if(!c1[i])
            break;
            printf("%d\n",i);
    }
    return 0;
} 



 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值