POJ1011

Description

George took sticks of the same length and cut them randomly until all parts became at most 50 units long. Now he wants to return sticks to the original state, but he forgot how many sticks he had originally and how long they were originally. Please help him and design a program which computes the smallest possible original length of those sticks. All lengths expressed in units are integers greater than zero.

问题:不知道原长和不知道木棍的数量,从L*N的木棍里切除了一堆小木棍(长度一样的小木棍可能很多)

分析1:从里面选最大木棍,假设它现在是原长。如果选最小的木棍必定无法涵盖最大木棍。(这一步需要对木棍从大到小排序)

分析2:假设的原长(说它是length),如果length无法整除sum,说明有剩的多余的木棍,所以这不是原长。(这一步length++)

分析3:(剪枝+遍历)如果现在探索的原长(既cur)是0,那么就得从小木棍里面选最长的,并记录已经走过这个木棍,用过这个木棍(x++)(if(cur==0))

分析4:(剪枝+遍历)从当前没走过的最大的小木棍开始,往更小的木棍开始,跳过原先走过且数值一样的木棍,加没有超过length的小木棍到里面,然后更新cur

分析5:(剪枝+遍历)如果cur==length,而且所有的小木棍都走过了,说明这就是原长,跳出

以上就是分析过程

now,自己写糊了几遍(md真的手残),看了别人的代码,再找到错误,再改后:

复制代码
#include <iostream>
#include<cstdlib>
#include<cstdio>
#include<stack>
#include<algorithm>
#include<cstring>
using namespace std;
int n,flag=0;
int stick[10000],k[10000];
int length,sum=0;
bool cmp(int a,int b){
    return a>b;
}
void dfs(int cur,int x,int w){
    if(flag)
        return;
    if(cur==0){
        int m=0;
        while(k[m])m++;
        k[m]=1;
        dfs(stick[m],x+1,m+1);
        k[m]=0;
        return;
    }
    if(cur==length){
        if(x==n){
            flag=1;
        }else{
            dfs(0,x,0);
        }
        return;
}
    for(int i=w;i<n;i++)
        if(!k[i]&&cur+stick[i]<=length){
            if(!k[i-1]&&stick[i-1]==stick[i]){
                continue;
            }
            k[i]=1;
            dfs(cur+stick[i],x+1,i+1);
            k[i]=0;
        }
    
}


int main(){
    while(scanf("%d",&n)&&n){
        memset(stick,0,sizeof(stick));
        sum=0;
        flag=0;
        for(int i=0;i<n;i++){
            scanf("%d",&stick[i]);
            sum+=stick[i];
        }
        sort(stick,stick+n,cmp);
        for(length=stick[0];length<sum;length++){
            if(sum%length==0){
                memset(k,0,sizeof(k));
                dfs(0,0,0);
                if(flag)
                    break;
            }
        }
        printf("%d\n",length);
    }
    
    return 0;
}
复制代码

 

posted @   A1han  阅读(44)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示