CSP-J/S 2024 第二轮 入门级 小木棍 题解
CSP-J/S 2024 第二轮 入门级 小木棍 题解
题目来源:ET题库 - 小木棍
题目分析
这是一道关于数字构造的题目。主要需要考虑:
- 每个数字需要的木棍数量不同
- 不能有前导零
- 要求构造出最小的数字
解题思路
- 首先统计每个数字(0-9)需要的木棍数量
- 对于给定的n根木棍,我们需要:
- 判断是否能构造出合法数字
- 如果可以,找出最小的合法数字
代码实现
#include <bits/stdc++.h>
using namespace std;
// 每个数字需要的木棍数量
const int sticks[] = {6, 2, 5, 5, 4, 5, 6, 3, 7, 6}; // 0-9分别需要的木棍数
// 判断能否用n根木棍构造出长度为len的数字
bool can_construct(int n, int len) {
if (len == 1) return n == sticks[1] || n == sticks[7] || n == sticks[4];
return n >= 2; // 长度大于1时,总能构造出某个数字
}
// 构造最小的数字
string construct_min(int n) {
// 特判无法构造的情况
if (n < 2) return "-1";
string result;
// 处理第一位(不能为0)
for (int i = 1; i <= 9; i++) {
if (sticks[i] <= n) {
result += ('0' + i);
n -= sticks[i];
break;
}
}
// 如果还有剩余木棍,尽量构造最小的数字
while (n > 0) {
bool found = false;
for (int i = 0; i <= 9; i++) {
if (sticks[i] <= n) {
result += ('0' + i);
n -= sticks[i];
found = true;
break;
}
}
if (!found) break;
}
return n == 0 ? result : "-1";
}
int main() {
freopen("sticks.in", "r", stdin);
freopen("sticks.out", "w", stdout);
int T;
cin >> T;
while (T--) {
int n;
cin >> n;
cout << construct_min(n) << endl;
}
return 0;
}
代码解释
1. 预处理数据
const int sticks[] = {6, 2, 5, 5, 4, 5, 6, 3, 7, 6};
存储每个数字需要的木棍数量。
2. 构造最小数字
string construct_min(int n) {
// 处理第一位(不能为0)
for (int i = 1; i <= 9; i++) {
if (sticks[i] <= n) {
result += ('0' + i);
n -= sticks[i];
break;
}
}
// ...
}
- 先处理第一位,必须是非零数字
- 然后贪心地选择剩余位数
关键点分析
- 贪心策略:
- 第一位选择需要最少木棍的非零数字
- 后续位置选择需要最少木棍的数字(可以是0)
- 特殊情况处理:
- n < 2 的情况无法构造
- 需要考虑木棍数量不足的情况
时间复杂度分析
- 对于每组测试数据:O(n)
- 总时间复杂度:O(T * n),其中T是测试数据组数
注意事项
- 文件输入输出
freopen("sticks.in", "r", stdin); freopen("sticks.out", "w", stdout);
- 边界条件
- 考虑无法构造的情况
- 注意前导零的处理
总结
这道题的关键在于:
- 正确统计每个数字需要的木棍数量
- 使用贪心策略构造最小数字
- 注意处理特殊情况
希望这个题解对你有帮助!如果有任何问题,欢迎在评论区讨论。