题目大意:
读入n个字符串,按字典序排序,再按列优先输出,附加条件每行最多输出60个字符,在此条件下要求行最少。(最开始没仔细看题,以为在一行中,每个单词相隔最长单词的长度+2,最后一列单词空间长度为最长单词的长度,不够用空格补齐。o(╥﹏╥)o。)
注意点:
1、求行数和列数时,容易想到的方法是O(n)复杂度的遍历求法,但可以优化为复杂度为O(1)的求法。
2、如果对本题求解过程有清晰的阶段划分,做起来会事半功倍。
最好遵循螺旋模型的法则:将整道题分为若干阶段,每完成一阶段就测试一下这以前求的值是否正确,如果错了,马上改正,确保减少后期Debug的时间。
如:1、将输入串存入数组后,输出数组,检测是否正确存入; 2、求出行数和列数后,输出行列数,检测是否正确求出。 期间保证测试多组数据。
3、一维数组按列输出为二维数组的方法: 当前列*总行数+当前行数。 一维数组按行输出为二维数组同理。
题目(提交)链接→UVa-400
如果不会用vJudge网站,请猛戳这里→vJudge教程
这段代码借鉴了刘先生求行列数和按列输出的技巧,但没有写print函数,采用#include<iomanip>
头文件中的setw()
和setiosflags()
设置域宽和左对齐。(代码在第20行)
代码:
#include<bits/stdc++.h>
using namespace std;
const int Maxcols = 60;
int main() {
int n; while(cin >> n) {
vector<string>s;
int Max = 0;
for(int i = 0; i < n; i++) {
string x; cin >> x;
s.push_back(x);
Max > x.length() ? : Max = x.length();
}
sort(s.begin(), s.end());
int cols = (Maxcols-Max)/(Max+2)+1, rows = ((s.size()+(cols-1))/cols); //求行数和列数
for(int i = 0; i < 60; i++) cout << '-'; cout << endl; //输出------------
for(int r = 0; r < rows; r++) { //按列输出序列
for(int c = 0; c < cols; c++) {
int idx = c * rows + r;
if(idx < s.size()) //setw(x)是设置x长的域宽,setiosflags()用来设置左对齐or右对齐;
cout << (c==cols-1?setw(Max):setw(Max+2)) << setiosflags(ios::left)<<s[idx];
}
cout << "\n";
}
}
return 0;
}
收获:
1、螺旋模型测试程序(分成若干阶段,完成一阶段进行值测试,若值不正确,则迭代修改)
2、按列输出(一维数组,列*总行数+当前行数)
可优化的:
1、o(1)复杂度求行和列
2、const常量代替常数