題目的難點在于要求前面的每一列的是最大長度L+2,最后一列的長度是L。對于寬度為WIDTH=60的一行來說,一行可以放下多少個單詞決定了需要多少行,知道了行數才能開始根據行數開始放置。
我的做法是col = (WIDTH+ 2) / (L + 2)
,即提前給WIDTH
加2,這個是給最后一列加的,因為實際上最后一列會減去這個2,所以加2沒有影響。
看了一下書中的做法,是col = (WIDTH - L) / (L + 2) + 1
,即先把最后一列減去,因為L <= WIDTH
,所以可以保證col
大于0,效果相同。
然后對于第i
行第j
列,我們要判斷在實際排好序的單詞數組中的位置,最后一行還需要判斷是否已經結束(因為最后一行有可能沒有滿)
書中是自己寫了一個控制輸出流的,我用的是C++自己的流控制,需要iomanip
頭文件,然后使用操縱符setw
設置最小寬度,使用left
控制左對齊(默認是右對齊)
需要注意algorithm
庫中的max
函數的兩個參數必須類型相同
#include <iostream>
#include <string>
#include <array>
#include <algorithm>
#include <sstream>
#include <iomanip>using namespace std;namespace {constexpr int MAXN = 105;constexpr int WIDTH = 60;array<string, MAXN> words;const string LINE(WIDTH, '-');int n;size_t max_len, word_len;int row, col, n_idx, idx;
}int main() {ios::sync_with_stdio(false);while (cin >> n) {ostringstream os;os << left;max_len = 0;for (int i = 0; i < n; ++i) {cin >> words[i];max_len = max(max_len, words[i].size());}sort(words.begin(), words.begin() + n);col = (WIDTH + 2) / (max_len + 2);row = (n - 1) / col + 1;for (int i = 0; i < row; ++i) {for (int j = 0; j < col; ++j) {idx = j * row + i;n_idx = (j + 1) * row + i;if (n_idx >= n) {word_len = max_len;} else {word_len = max_len + 2;}os << setw(word_len) << words[idx];if (word_len == max_len) {os << "\n";break;}}}cout << LINE << "\n";cout << os.str();}return 0;
}