/* @JUDGE_ID: 23756AW 400 C++ "IO Manipulators and Sorted Vector" */
This program has two real traps.
The first is that the last column in a row is equal the maximum
filename length. All the other preceding columns in the row are equal
to the maximum filename length + 2 (" "). This will impact the
calculation you use to determine how many filenames get outputted per
row (and how conversely how many rows are required to display all the
The second problem is in the fact that the filenames are sorted,
and displayed in column order rather than row order. This means that
you cannot simply use a sorted list and output the elements in order.
The rest of the problem is trivial as it only relates to formatting.
I have chosen the IO manipulators approach, but printf with format
specifiers also words. The nice thing about the IO manipulators is that
they are much more readable, and in my opinion offer a robust set of
options that can be used in later programs.
I chose to use the STL vector for the filenames because of the
ability to directly access filenames. This ability is important because
of the way the files are sorted going down the column. If they were
sorted across the row I would have used the STL list container class
instead which has a little less overhead and its own sort method.
STL sort algorithm works perfectly with an STL vector, and it can
be used later in other programs in a more complex manner. This program
is a good way to get used to the rudimentary usage of SORT and IO
1. The items_per_row calcuation will be
((MAX_LINE_LEN - max_filename_len)/(max_filename_len + 2)) + 1
2. The row_count calculation will be (total_filenames/items_per_row)
* If there is a remainder (total_filenames % items_per_row) then increment.
3. Each column of each row can be represented as
filenames[row_index + (col_index * row_count)]
1. This is accepted but has a P.E.
2. IO manipulators implementation (like "left") are not supported by
the compiler that JUDGE is using.
If you have any problems with this program or want an explanation about the
code feel free to email me at email@example.com
#pragma warning (disable:4786)
using namespace std;
#define MAX_LINE_LEN 60
void main ()
int count = 0;
int max_len = 0;
int items_per_line = 1;
int row_count = 1;
int row_index = 0;
int col_index = 0;
int item_count = 0;
while (cin >> count)
if (! count)
| This is a slick way of outputting the 60 dashes without any errors.
cout << setw(60) << setfill('-') << "" << endl;
Need to reset the fill character to spaces before any more output.
This could have been done by passing the IO manipulator into the
cout stream (like cout << setfill(' ') << filename), but I wanted
to demonstrate that there are two approaches in C++ to achieve the
max_len = 0;
cin >> filename;
if (filename.length() > max_len)
max_len = filename.length();
| Calculate how many filenames will be outputted on each line.
| The calculation is based on the fact that the last column has
| a column width different than the other columns. Therefore to
| get the right calculation you must do the following:
| 1. Subtract the column width of the last column from the allowed line length.
| 2. Divide the column width of the other columns (last_col_width + 2) into the
| maximum line length - the last_col_width.
| 3. The result of #2 is the number of items that can precede the last column,
| therefore you must add 1 to the items_per_line variable.
items_per_line = (MAX_LINE_LEN - max_len)/(max_len + 2);
| Now we want to know how many rows will be outputted. Once we
| have the items_per_line all we have to do is divide that into
| the total number of files. Because of integer division round-off
| errors we may need to add 1 if there is a remainder in the division.
| For example: if items_per_line=5 and file_count=19 then 19/5 = 3 rows,
| but we need a 4th row to store the 16th through 19th files.
row_count = flist.size()/items_per_line;
if (flist.size() % items_per_line)
| Outputting the file list is a little tricky because the sort goes down
| the column instead of across the row. As a result we are fortunate to
| have a sorted array like structure that allows us direct access to the
| files by an index value. To calculate what index should be used for the
| row output we simply take the current row index and add the row count.
| IE: Suppose we have a vector in form A,B,C,C,D,F,G,G and the row_count is 3:
| row0,col0 = vector
| row0,col1 = vector[0+3]
| row0,col2 = vector[0+6]
| repeat using form rowX,colY = vector[X + (Y*row_count)]
| The above would give us A C G
| B D G
| C F
| We need to be sure that if we exceed the vector's boundary that we exit the output
| because we are obviously done.
for (row_index = 0; row_index < row_count; ++row_index)
| Set cout to left justify the output and have a fixed width equal the maximum
| filename length. I normally would have used the IO manipulator "left"
| (like cout << left << filename) but the Online Judge's compiler does not
| seem to like that, even though the Visual C++ compiler allows it. To work
| around it I set the IO stream flags directly.
cout << setw(max_len) << flist[row_index];
for (col_index = 1; col_index<items_per_line; ++col_index)
int findex = row_index + (col_index * row_count);
if (findex >= flist.size())
col_index = items_per_line;
cout << " " << setw(max_len) << flist[findex];
cout << endl;
| Flush the vector and prepare for a new file list.