题目链接
题目描述
给定一个由字符 '0' 和 '1' 构成的字符串 。我们从字符串开头开始,按照一个循环变化的长度规则依次取出以下子串并解析为十进制数:
- 长度 1 的子串;
- 长度 2 的子串;
- ...
- 长度 10 的子串;
- 然后循环回长度 1,依此类推;
子串被取走后,视为从原字符串中删除,下一次从剩余的字符串开头继续取。直到剩余字符不足以组成当前所需长度的子串时,解析过程结束。
请输出解析得到的十进制数字序列。
输入:
- 一个由 '0' 和 '1' 构成的字符串
。
输出:
- 第一行输出一个整数
,表示解析得到的数字个数。
- 第二行输出
个整数,表示所有解析出的十进制数字,数字之间用空格隔开。
解题思路
这是一个直接的模拟问题,我们只需要按照题目描述的规则逐步切分字符串即可。
我们可以维护两个核心变量:
- 一个指针
,记录当前应当从字符串的哪个位置开始切分。
- 一个变量
,记录当前需要切分的子串长度。
算法的详细步骤如下:
- 初始化
为 0,
为 1。
- 初始化一个列表
用于存储解析出的十进制数。
- 进入一个循环,循环的条件是剩余字符串的长度不小于当前需要切分的长度,即
。
- 在循环中:
a. 从字符串
中,截取从
开始,长度为
的子串。 b. 将这个二进制子串转换为十进制整数。 c. 将转换后的整数添加到
列表中。 d. 更新
,将它的值增加
,以指向下一次切分的起始位置。 e. 更新
。根据题意,长度从 1 递增到 10,然后重新循环回 1。所以我们将
加 1,如果它超过 10,就将它重置为 1。
- 当循环结束时(因为剩余字符串长度不足),
列表中就包含了所有按规则解析出的数字。
- 最后,按照题目要求的格式输出
的大小和内容。
代码
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
void solve() {
string s;
cin >> s;
vector<long long> results;
int current_index = 0;
int current_length = 1;
// 当剩余字符串足够长时,继续切分
while (current_index + current_length <= s.length()) {
// 截取子串
string sub = s.substr(current_index, current_length);
// 将二进制子串转为十进制数,并存入结果
results.push_back(stoll(sub, nullptr, 2));
// 更新下一次切分的起始位置
current_index += current_length;
// 更新下一次切分的长度 (1-10 循环)
current_length++;
if (current_length > 10) {
current_length = 1;
}
}
// 输出结果数量
cout << results.size() << endl;
// 输出结果序列
for (size_t i = 0; i < results.size(); ++i) {
cout << results[i] << (i == results.size() - 1 ? "" : " ");
}
cout << endl;
}
int main() {
solve();
return 0;
}
import java.util.Scanner;
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String s = sc.nextLine();
List<Integer> results = new ArrayList<>();
int currentIndex = 0;
int currentLength = 1;
// 当剩余字符串足够长时,继续切分
while (currentIndex + currentLength <= s.length()) {
// 截取子串
String sub = s.substring(currentIndex, currentIndex + currentLength);
// 将二进制子串转为十进制数,并存入结果
results.add(Integer.parseInt(sub, 2));
// 更新下一次切分的起始位置
currentIndex += currentLength;
// 更新下一次切分的长度 (1-10 循环)
currentLength++;
if (currentLength > 10) {
currentLength = 1;
}
}
// 输出结果数量
System.out.println(results.size());
// 输出结果序列
for (int i = 0; i < results.size(); i++) {
System.out.print(results.get(i) + (i == results.size() - 1 ? "" : " "));
}
System.out.println();
}
}
def solve():
s = input()
results = []
current_index = 0
current_length = 1
# 当剩余字符串足够长时,继续切分
while current_index + current_length <= len(s):
# 截取子串
sub = s[current_index : current_index + current_length]
# 将二进制子串转为十进制数,并存入结果
results.append(int(sub, 2))
# 更新下一次切分的起始位置
current_index += current_length
# 更新下一次切分的长度 (1-10 循环)
current_length += 1
if current_length > 10:
current_length = 1
# 输出结果数量
print(len(results))
# 输出结果序列
print(*results)
solve()
算法及复杂度
- 算法:模拟
- 时间复杂度:
,其中
是字符串的长度。我们通过指针移动的方式,整个字符串的每个字符实际上只被访问和处理常数次。
- 空间复杂度:
,用于存储解析出的十进制数。平均切分长度是 5.5,所以结果数量级约为
,即
。

京公网安备 11010502036488号