2 条题解

  • 0
    @ 2023-1-31 21:01:35
    #include<stdio.h>
    #include<algorithm>
    using namespace std;
    int n;
    int a[100],book[100];
    bool cmp(int x,int y)
    {
        return x>y;
    }
    int len,cnt;
    int dfs(int num,int lasti,int l)
    {
        //num为拼好的个数,lasti为上一个的编号,l为已拼成的长度
        if(num==cnt+1) //表示拼成了cnt根小木棍且小木棍没有剩余,符合题目所求
            return 1;
        if(l==len)//拼成一个len长度num+1
            return dfs(num+1,1,0);
        for(int i=lasti; i<=n; i++)//剪枝,当用木棍i拼接最初的木棍时,可以从第i+1后的木棍开始搜索,因为排序,前面的木棍已经用过了
        {
            if(!book[i]&&l+a[i]<=len)  //保证当前长度加上正在选的小木棍长度不大于len,如果大于len就是没有小木棍可以拼成len长度的小木棍,不符合条件
            {
                book[i]=1;
                if(dfs(num,i+1,l+a[i]))
                    return 1;
                book[i]=0;//深搜搜索后要取消标记
                if(l==0||l+a[i]==len)//剪枝,找不到能拼成len长度的木棍
                    return 0;
                while(a[i]==a[i+1])//去重剪枝 相同长度的不符合条件的则不需再搜索
                    i++;
            }
        }
        return 0;
    }
    int main()
    {
        scanf("%d",&n);
        int s=0;
        //排序,最初小木棍的长度一定大于等于砍断后的小木棍的最大的长度,并且小于所有小木棍的长度之和
        for(int i=1; i<=n; i++)
        {
            scanf("%d",&a[i]);
            s+=a[i];
        }
        sort(a+1,a+1+n,cmp);
        //所有小木棍的长度之和为s,则拼成若干根的小木棍的长度一定能被s整除,否则就拼不成,因为拼成的小木棍必须是整数根
        for(len=a[1]; len<=s; len++)
        {
            if(s%len==0)
            {
                cnt=s/len;
                if(dfs(1,1,0))
                    break;
            }
        }
        printf("%d\n",len);
        return 0;
    }
    

    信息

    ID
    1204
    时间
    1000ms
    内存
    512MiB
    难度
    8
    标签
    递交数
    12
    已通过
    9
    上传者