题目描述

小 S 喜欢收集小木棍。在收集了 n 根长度相等的小木棍之后,他闲来无事,便用它们拼起了数字。用小木棍拼每种数字的方法如下图所示。

现在小 S 希望拼出一个整数,满足如下条件:

  • 拼出这个数恰好使用 n 根小木棍;
  • 拼出的数没有前导 0;
  • 在满足以上两个条件的前提下,这个数尽可能小。

小 S 想知道这个数是多少,可 n 很大,把木棍整理清楚就把小 S 折腾坏了,所以你需要帮他解决这个问题。如果不存在正整数满足以上条件,你需要输出 −1 进行报告。

输入格式

本题有多组测试数据。

输入的第一行包含一个正整数 T,表示数据组数。

接下来包含 T 组数据,每组数据的格式如下:

一行包含一个整数 n,表示木棍数。

输出格式

对于每组数据:输出一行,如果存在满足题意的正整数,输出这个数;否则输出 −1。

输入输出样例

输入 #1复制

5
1
2
3
6
18

输出 #1复制

-1
1
7
6
208

说明/提示

【样例 1 解释】

  • 对于第一组测试数据,不存在任何一个正整数可以使用恰好一根小木棍摆出,故输出 −1。
  • 对于第四组测试数据,注意 0 并不是一个满足要求的方案。摆出 9、41 以及 111 都恰好需要 6 根小木棍,但它们不是摆出的数最小的方案。
  • 对于第五组测试数据,摆出 208 需要 5+6+7=18 根小木棍。可以证明摆出任何一个小于 208 的正整数需要的小木棍数都不是 18。注意尽管拼出 006 也需要 18 根小木棍,但因为这个数有前导零,因此并不是一个满足要求的方案。

【数据范围】

对于所有测试数据,保证:1≤T≤50,1≤n≤105。

测试点编号n≤特殊性质
120
250
3103A
4,5105A
6103B
7,8105B
9103
10105

特殊性质 A:保证 n 是 7 的倍数且 n≥100。

特殊性质 B:保证存在整数 k 使得 n=7k+1,且 n≥100。

题目概述与分析

小木棍问题是2024年CSP-J竞赛中的一道经典题目,考察选手对搜索算法和剪枝优化的掌握。题目描述有n根长度不同的小木棍,需要将它们拼接成若干根长度相同的长木棍,求可能的最小原始长木棍长度。

这个问题可以建模为组合优化问题,需要综合考虑所有可能的组合方式。我们将介绍两种不同的解法:深度优先搜索(DFS)剪枝法和动态规划法。

解法一:DFS剪枝法

算法思路

  1. 使用深度优先搜索尝试所有可能的组合
  2. 通过多种剪枝策略优化搜索效率
  3. 从最大可能长度开始向下搜索
  4. 时间复杂度取决于剪枝效果,最坏情况下O(n!)
#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
using namespace std;vector<int> sticks;
vector<bool> used;
int n, total_len, max_len;bool dfs(int cnt, int cur_len, int start, int target) {if (cnt == total_len / target) return true;if (cur_len == target) return dfs(cnt + 1, 0, 0, target);for (int i = start; i < n; ++i) {if (!used[i] && cur_len + sticks[i] <= target) {if (i > 0 && sticks[i] == sticks[i-1] && !used[i-1]) continue;used[i] = true;if (dfs(cnt, cur_len + sticks[i], i + 1, target)) return true;used[i] = false;if (cur_len == 0) break;}}return false;
}int main() {cin >> n;sticks.resize(n);used.resize(n, false);total_len = 0;max_len = 0;for (int i = 0; i < n; ++i) {cin >> sticks[i];total_len += sticks[i];max_len = max(max_len, sticks[i]);}sort(sticks.begin(), sticks.end(), greater<int>());for (int len = max_len; len <= total_len; ++len) {if (total_len % len != 0) continue;fill(used.begin(), used.end(), false);if (dfs(0, 0, 0, len)) {cout << len << endl;return 0;}}cout << total_len << endl;return 0;
}

该实现使用DFS加多种剪枝策略,包括排序优化、跳过重复值和提前终止等,能有效提高搜索效率。

解法二:动态规划法

算法思路

  1. 将问题转化为背包问题的变种
  2. 使用位运算状态压缩
  3. 记录可达的长度组合
  4. 时间复杂度O(n*sum),适合sum较小的情况
#include <iostream>
#include <vector>
#include <algorithm>
#include <bitset>
using namespace std;int main() {int n;cin >> n;vector<int> sticks(n);int sum = 0;for (int i = 0; i < n; ++i) {cin >> sticks[i];sum += sticks[i];}sort(sticks.begin(), sticks.end());for (int len = sticks.back(); len <= sum; ++len) {if (sum % len != 0) continue;int k = sum / len;vector<bitset<100>> dp(k + 1);dp[0][0] = 1;for (int stick : sticks) {for (int i = k; i >= 0; --i) {for (int j = len; j >= 0; --j) {if (dp[i][j]) {if (j + stick <= len) {dp[i][j + stick] = 1;}if (i + 1 <= k && stick <= len) {dp[i + 1][stick] = 1;}}}}}if (dp[k][0]) {cout << len << endl;return 0;}}cout << sum << endl;return 0;
}

动态规划解法通过状态压缩记录可达的长度组合,适合小规模数据,但空间复杂度较高。

算法对比分析

方法时间复杂度空间复杂度适用场景
DFS剪枝法取决于剪枝效果O(n)数据规模中等,剪枝有效
动态规划法O(n*sum)O(k*len)sum值较小的情况

关键问题详解

剪枝策略优化

  1. 从大到小排序木棍,优先尝试长木棍
  2. 跳过相同长度的重复尝试
  3. 当前组合失败时及时回溯
  4. 限制搜索的起始位置避免重复

边界情况处理

  1. 所有木棍长度相同的情况
  2. 无法分割的情况
  3. 极端大规模数据测试
  4. 包含长度为1的木棍的情况

性能优化建议

  1. 预处理时计算所有可能的候选长度
  2. 使用更高效的数据结构存储状态
  3. 并行化处理可能的候选长度
  4. 提前终止不可能的组合

数学原理分析

  1. 组合数学中的分割问题
  2. 数论中的因数分解应用
  3. 搜索算法的剪枝理论
  4. 动态规划的最优子结构性质

实际应用价值

这类算法在以下领域有重要应用:

  1. 资源分配与调度
  2. 货物装载优化
  3. 时间表安排
  4. 工业生产中的材料切割

扩展思考

  1. 如果木棍有不同颜色限制如何处理?
  2. 如果允许部分不匹配的情况怎么解决?
  3. 如何扩展到三维空间的材料分割?
  4. 多目标优化情况下如何调整算法?

掌握这类组合优化问题的解法,不仅能提升竞赛能力,也对解决实际工程问题有很大帮助。建议先理解基础算法原理,再针对具体问题特点进行优化。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/90222.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/90222.shtml
英文地址,请注明出处:http://en.pswp.cn/bicheng/90222.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C# 继承 虚方法

继承 虚方法 &#xff08;重写&#xff09; virtual 虚方法的关键字 override 重写的关键字 练习&#xff1a; 继承 继承&#xff1a;很多类有相似的数据 相同的属性 相同的方法 也有不同的 这个时候就可以使用继承 让多个类去继承自某个具有相同数据的基类(父类) 这…

Java 堆(优先级队列)

文章目录优先级队列模拟实现优先级队列向下调整建堆向上调整建堆堆的删除priorityQueue构造方法大根堆和小根堆的向上调整比较方法扩容面试题堆排序优先级队列 priorityqueue&#xff1a;底层是一颗完全二叉树 小根堆&#xff1a;根比左右孩子都小大根堆&#xff1a;根比左右…

在.NET Core API 微服务中使用 gRPC:从通信模式到场景选型

目录 一、gRPC 基础&#xff1a;为什么它适合微服务&#xff1f; 二、gRPC 的四种通信模式及.NET Core 实现 1. 一元 RPC&#xff08;Unary RPC&#xff09;&#xff1a;最基础的请求 - 响应模式 2. 服务器流式 RPC&#xff08;Server Streaming RPC&#xff09;&#xff1…

HTML零基础快速入门教程(详细篇)

本文详细介绍HTML零基础快速入门的基础知识&#xff0c;包括HTML的介绍、语言的一些实际作用、语法规范注意&#xff0c;如标签结构、标签属性、大小写不敏感等&#xff0c;还介绍了HTML文件的具体书写规则&#xff0c;如文件扩展名、文档类型声明和HTML结构以及具体的一些HTML…

LLM评测框架Ragas:SQL指标(解决了Ollama推理框架不支持的问题)

SQL类的度量指标是指运行SQL后的结果和预期之间的一个度量值。 datacompy score datacompy score 使用DataCompy(一个比较pandas的数据格式的python类,所以需要按照datacompy:pip install datacompy),默认是按照rows比较,也可以设置按照columns比较,这个事通过mode参数…

ubuntu24 ros2 jazzy

安装2 software & update 选择其它 安装 一、前提准备 检查操作系统版本&#xff1a; 确保你的系统版本是Ubuntu 24.04。你可以通过运行lsb_release -a命令来检查当前的系统版本。 设置UTF-8支持&#xff1a; ROS 2需要UTF-8编码支持。你可以通过以下命令来检查和设置UTF…

设备虚拟化技术

设备虚拟化技术概述设备虚拟化技术通过软件模拟物理硬件设备&#xff0c;使多个操作系统或应用程序能够共享同一台物理设备。它广泛应用于云计算、服务器整合和测试环境等领域。核心目标是提高资源利用率、隔离性和灵活性。•当接入的用户数增加到原交换机端口密度不能满足接入…

开发避坑短篇(3):解决@vitejs plugin-vue@5.0.5对Vite^5.0.0的依赖冲突

异常信息 # npm resolution error reportWhile resolving:system3.8.8 Found: vite6.2.3 node_modules/vitedev vite"6.2.3" from the root projectCould not resolve dependency: peer vite"^5.0.0" from vitejs/plugin-vue5.0.5 node_modules/vitejs/plu…

k8s快速部署(亲测无坑)

文章目录k8s快速部署&#xff08;亲测无坑&#xff09;一、网络划分二、CentOS7设置 标题固定IP和阿里云YUM源三、主机环境配置四、虚拟机的拷贝五、安装docker(每台主机都需要安装)六、安装kubelet,kubeadm,kubectl(每台机器都需要执行)遇到的问题参考文档k8s快速部署&#xf…

简易RAG问答引擎的构建与体验

RAG&#xff08;检索增强生成&#xff09;是结合检索与生成式 AI 的技术框架。核心逻辑是先从外部知识库精准检索相关信息&#xff0c;再将其作为上下文输入大模型生成回答。技术上依赖检索引擎&#xff08;如向量数据库、BM25&#xff09;、大语言模型&#xff08;如 GPT、LLa…

C++11特性学习 Day1

nullptr对于c中null (void*)0&#xff0c;所以在为函数传参传入0时&#xff0c;无法清楚地分辨是int类型的0还是指的是空指针null在C11中清晰的将空指针变为了nullptr&#xff0c;0专指int型的数字0override关键字在子类中对父类的函数的覆写之后加上override关键字&#xff0…

微算法科技(NASDAQ: MLGO)探索优化量子纠错算法,提升量子算法准确性

随着量子计算技术的飞速发展&#xff0c;量子计算机在解决复杂计算问题上的潜力日益显现。然而&#xff0c;量子计算面临的一个重大挑战是量子比特的脆弱性&#xff0c;即量子比特容易受到环境噪声和干扰的影响&#xff0c;导致量子态的塌缩和计算结果的错误。微算法科技&#…

MongoDB数据库详解-针对大型分布式项目采用的原因以及基础原理和发展-卓伊凡|贝贝|莉莉

MongoDB数据库详解-针对大型分布式项目采用的原因以及基础原理和发展-卓伊凡|贝贝|莉莉由于老产品即时通讯私有化软件就是采用MongoDB &#xff0c;但是版本实在太低&#xff0c;要做大更新&#xff0c;其次针对10年前完美运营的项目来到10年后的现在就不一定行&#xff0c;优雅…

Kotlin 中的单例模式(Singleton)与对象声明

在 Kotlin 中&#xff0c;类描述的是一种通用结构&#xff0c;可以多次实例化&#xff0c;也可以用多种方式实例化。但有时我们只需要单个实例&#xff0c;不多不少。单例模式能帮你更好地组织代码&#xff0c;把相关的方法聚合在一起。 单例模式是什么&#xff1f; 单例模式是…

Shell 编程基础入门从认识到实战

对于刚接触 Linux 或 Unix 系统的开发者来说&#xff0c;Shell 脚本往往是自动化操作的第一道门槛。它不像 Python 那样语法简洁&#xff0c;也不像 Java 那样有完善的面向对象体系&#xff0c;但却能以极少的代码实现强大的系统管理功能。本文将从 Shell 的基本概念讲起&#…

混合遗传粒子群算法在光伏系统MPPT中的应用研究

混合遗传粒子群算法在光伏系统MPPT中的应用研究 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家&#xff0c;觉得好请收藏。点击跳转到网站。 摘要 本文针对光伏系统最大功率点跟踪(MPPT)问题&#xff0…

机器视觉的布料丝印应用

在纺织印染行业&#xff0c;布料丝印工艺的精度直接决定产品外观质量与市场竞争力。传统丝印设备依赖机械定位与人工校准&#xff0c;面对高密度图案、柔性面料或复杂纹理时&#xff0c;易出现套色偏移、油墨渗透不均等问题&#xff0c;导致良品率波动与生产成本攀升。 随着机…

前端常用类库

常用类库 类库作用 类库可以帮助我们快速实现项目业务的开发与功能的实现, 帮助我们解放劳动力提高生产效率, 前端中的类库与框架都是由原生javascript编写, 提供给其他开发者应用于某一业务环境或者需求。一般有开发者/团队开源维护. 优秀的类库需要具备高度封装可用, 稳定, …

通俗易懂循环神经网络(RNN)指南

本文用直观类比、图表和代码&#xff0c;带你轻松理解RNN及其变体&#xff08;LSTM、GRU、双向RNN&#xff09;的原理和应用。什么是循环神经网络 循环神经网络&#xff08;Recurrent Neural Network, RNN&#xff09;是一类专门用于处理序列数据的神经网络。与前馈神经网络不同…

【SVM】支持向量机实例合集

基于Java的SVM(支持向量机)实例合集 以下是一个基于Java的SVM(支持向量机)实例合集,包含核心代码示例和应用场景说明。这些例子基于流行的机器学习库(如LIBSVM、Weka、JSAT)实现。 数据准备与加载 使用LIBSVM格式加载数据集: // 加载LIBSVM格式数据 svm_problem pr…