顺序扫描单词,维护当前行非空格字符数,放不下时换行输出。
OJ: usaco
题目 ID: 987
难度:入门
标签:模拟字符串
日期: 2026-07-11 14:24
题意
给定 N 个单词和每行字符上限 K。
需要按顺序输出这些单词,使每一行的非空格字符数不超过 K。如果下一个单词放入当前行会超过 K,就把它放到下一行。
同一行单词之间用一个空格分隔,行末不能有多余空格。
思路
朴素模拟
可以先把每一行的单词保存下来,最后统一输出:
cpp
/**
* Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
* rbook: -> https://rbook.roj.ac.cn https://rbook2.roj.ac.cn
* rainboy的学习导航网站: https://idx.roj.ac.cn
* create_at: 2026-07-11 14:24
* update_at: 2026-07-11 14:25
*/
// brute.cpp:小数据暴力解,用来帮助理解题意并辅助对拍。
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 105;
int n, k;
string word[MAXN]; // 第 i 个单词
vector<string> lines[MAXN];
int line_cnt;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin >> n >> k;
for (int i = 1; i <= n; i++) {
cin >> word[i];
}
line_cnt = 1;
int current_len = 0;
// 朴素模拟:先把单词放进每一行的数组里,最后统一输出。
for (int i = 1; i <= n; i++) {
int len = (int)word[i].size();
if (current_len + len > k) {
line_cnt++;
current_len = 0;
}
lines[line_cnt].push_back(word[i]);
current_len += len;
}
for (int i = 1; i <= line_cnt; i++) {
for (int j = 0; j < (int)lines[i].size(); j++) {
if (j > 0) {
cout << ' ';
}
cout << lines[i][j];
}
cout << '\n';
}
return 0;
}这个写法非常直观:每个单词要么加入当前行,要么新开一行。
边扫描边输出
正式代码可以不保存所有行,只维护一个变量:
text
current_len = 当前行已有的非空格字符数量对每个单词 w:
- 如果
current_len + len(w) > K,先输出换行,再输出w; - 否则把
w放在当前行,如果当前行已有单词,就在它前面输出一个空格。
注意空格不计入 current_len,所以更新长度时只加单词长度。
代码
cpp
/**
* Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
* rbook: -> https://rbook.roj.ac.cn https://rbook2.roj.ac.cn
* rainboy的学习导航网站: https://idx.roj.ac.cn
* create_at: 2026-07-11 14:24
* update_at: 2026-07-11 14:25
*/
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 105;
int n, k;
string word[MAXN]; // 第 i 个单词
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin >> n >> k;
for (int i = 1; i <= n; i++) {
cin >> word[i];
}
int current_len = 0; // 当前行已有的非空格字符数量
for (int i = 1; i <= n; i++) {
int len = (int)word[i].size();
if (current_len + len > k) {
cout << '\n' << word[i];
current_len = len;
} else {
if (current_len > 0) {
cout << ' ';
}
cout << word[i];
current_len += len;
}
}
cout << '\n';
return 0;
}复杂度
每个单词处理一次,时间复杂度为
保存单词数组,空间复杂度为
总结
这题的关键是分清“输出时需要空格”和“判断长度时不统计空格”。
只要维护当前行已有多少个非空格字符,就能直接模拟题目规则。