洛谷-1120 小木棍 [数据加强版]

本文探讨了一道有趣的编程挑战,乔治将木棍随意砍断,需通过算法找到原始木棍的最小可能长度。文章提供了详细的算法思路和剪枝技巧,包括从最大木板开始搜索、避免重复搜索、判断是否能凑成整块等关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述
乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过5050。
现在,他想把小木棍拼接成原来的样子,但是却忘记了自己开始时有多少根木棍和它们的长度。
给出每段小木棍的长度,编程帮他找出原始木棍的最小可能长度。
输入输出格式
输入格式:
共二行。
第一行为一个单独的整数N表示砍过以后的小木棍的总数,其中N≤65N≤65
(管理员注:要把超过50的长度自觉过滤掉,坑了很多人了!)
第二行为N个用空个隔开的正整数,表示N根小木棍的长度。
输出格式:
一个数,表示要求的原始木棍的最小可能长度

输入输出样例
输入样例#1:
9
5 2 1 5 2 1 5 2 1

输出样例#1:
6

解释:暴力很好写,主要是剪枝,这里有4点,1.从最大木板开始搜,2.按从大向小搜避免重复,3.如果凑成整块后,以后的小的凑不出来,那么必然凑不出来,4.如果刚开始后大的凑不出来,小的必然也凑不出来。

#include<cstdio>
#include<cstdlib>
const int N = 70 ;
int n , cnt , tot , maxn , minn , tm[ N ]; 
void dfs( int res , int sum , int target , int p ) {
    if(res==0){
        printf("%d", target  );
        exit(0);
    }
    if(sum==target){
        dfs(res - 1,0,target, maxn );
        return;
    }
    for( int i = p ; i >= minn ; i -- ){ 
        if( tm[ i ] && i + sum <= target ){
            tm[ i ] -- ;
            dfs( res , sum + i , target , i );
            tm[ i ] ++ ;
            if ( sum == 0 || sum + i == target )
                break;
        }
    }
    return;
}
int main() {
    scanf("%d" , &n ) ;
    minn = N ;
    int temp;
    while( n -- ) {
        scanf("%d" , &temp );
        if( temp <= 50 ) {
            cnt ++;
            tm[ temp ] ++;
            tot += temp;
            maxn = maxn > temp ? maxn : temp ; 
            minn = minn < temp ? minn : temp ;
        }
    }
    for( int i = maxn ; i <= tot ; i ++ ) {
        if( tot % i == 0 ) {
            dfs( tot / i , 0 , i , maxn );
        }
    }
    printf("%d" , tot );
    return 0;
}
### 关于洛谷平台上的拼木棒问题 #### 解题思路 对于洛谷P3799妖梦拼木棒这道题目,核心在于如何判断四根木棍能否组成一个矩形或正方形。为了简化问题并提高效率,可以采用以下策略: 1. **输入处理**:读取给定的多组数据,每组数据包含四个整数表示四根木棍长度。 2. **排序优化**:对每一组中的四个数值进行升序排列,这样便于后续比较操作[^1]。 3. **条件验证**: - 如果最长边等于其他三边之和,则无法构成任何图形; - 若最短两边相等且次长两根也相同,则可形成矩形; - 当所有四条边都一样时即为特殊情况下的正方形; 4. **输出结果**:根据上述逻辑得出结论后打印相应信息。 通过以上方法能够有效降低算法复杂度,并确保程序运行速度满足在线评测系统的时限要求。 #### 代码实现(C语言) 下面是基于上述分析编写的C语言版本解决方案: ```c #include <stdio.h> #include <stdlib.h> int cmp(const void *a, const void *b){ return *(int*)a - *(int*)b; } int main(){ int T; scanf("%d",&T); while(T--){ int a[4]; for(int i=0;i<4;++i)scanf("%d", &a[i]); qsort(a, 4, sizeof(int), cmp); if (a[3]>=a[0]+a[1]+a[2]) printf("No\n"); else if ((a[0]==a[1] && a[2]==a[3])) printf("Yes Square\n"); else if((a[0]==a[1] || a[1]==a[2] || a[2]==a[3])){ printf("Yes Rectangle\n"); }else{ printf("No\n"); } } return 0; } ``` 这段代码实现了完整的解题流程,包括输入解析、数组排序以及最终的结果判定与输出。其中`qsort()`函数用于快速完成内部元素顺序调整工作,而自定义比较器`cmp()`则保证了按照从小到大的原则来进行整理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值