400 - Unix ls
Moderator: Board moderators
-
- Guru
- Posts: 724
- Joined: Wed Dec 19, 2001 2:00 am
- Location: Germany
-
- New poster
- Posts: 8
- Joined: Tue Jul 23, 2002 2:38 am
- Location: High Point, North Carolina / Goodlettsville, Tennesee
- Contact:
Ok, thanks for pointing out the use of size() instead of length() and the extra two spaces at the end of the line. However, I'm afraid I'm confused by the following:
I do not have any idea what you mean by %0 and /0. And I assume 60/(longest+2) is wrong because the last column, unlike the ones before it, does not need 2 spaces at the end. Or am I completely misunderstanding you? ThanksAnd the Runtime error is because of %0 and /0. They occur because 60/(longest+2) is not the correct value.
-
- Guru
- Posts: 724
- Joined: Wed Dec 19, 2001 2:00 am
- Location: Germany
HELP ME please
i got wa many times...coulld you help me?
[pascal]var
s:array[1..102] of string;
i:integer;
procedure order(t:integer);
var
m,n:integer;
st:string;
begin
for m:=1 to t-1 do
for n:=m+1 to t do
if(s[m]>s[n]) then
begin
st:=s[m];
s[m]:=s[n];
s[n]:=st;
end;
end;
procedure print(t:integer);
var
i:integer;
begin
for i:=1 to t do
write(' ');
end;
procedure ru;
var
i,t,l,c,r,x,y:integer;
begin
l:=1;
readln(t);
for i:=1 to t do
begin
readln(s);
if length(s)>l then
l:=length(s);
end;
order(t);
for i:=1 to 60 do
write('-');
writeln;
c:=trunc(60/(l+2));
r:=trunc(t/c);
if(t/c<>r) then
inc(r);
l:=l+2;
for i:=1 to r do
begin
x:=i;
for y:=1 to c do
begin
if(x<=t) then
begin
write(s[x]);
print(l-length(s[x]));
end;
x:=x+r;
end;
writeln;
end;
// writeln(s.str);
end;
begin
while not eof do
begin
ru;
end;
end.[/pascal]
[pascal]var
s:array[1..102] of string;
i:integer;
procedure order(t:integer);
var
m,n:integer;
st:string;
begin
for m:=1 to t-1 do
for n:=m+1 to t do
if(s[m]>s[n]) then
begin
st:=s[m];
s[m]:=s[n];
s[n]:=st;
end;
end;
procedure print(t:integer);
var
i:integer;
begin
for i:=1 to t do
write(' ');
end;
procedure ru;
var
i,t,l,c,r,x,y:integer;
begin
l:=1;
readln(t);
for i:=1 to t do
begin
readln(s);
if length(s)>l then
l:=length(s);
end;
order(t);
for i:=1 to 60 do
write('-');
writeln;
c:=trunc(60/(l+2));
r:=trunc(t/c);
if(t/c<>r) then
inc(r);
l:=l+2;
for i:=1 to r do
begin
x:=i;
for y:=1 to c do
begin
if(x<=t) then
begin
write(s[x]);
print(l-length(s[x]));
end;
x:=x+r;
end;
writeln;
end;
// writeln(s.str);
end;
begin
while not eof do
begin
ru;
end;
end.[/pascal]
400 - Solution with Full Documentation
[cpp]
/* @JUDGE_ID: 23756AW 400 C++ "IO Manipulators and Sorted Vector" */
/*
PROBLEM_ID: 400
SYNOPSIS:
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
filenames).
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.
CODE NOTES;
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
manipulators.
SOLUTION NOTES:
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)]
KNOWN ISSUES:
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.
AUTHOR NOTES:
Scott Lane
If you have any problems with this program or want an explanation about the
code feel free to email me at scolane@comcast.net.
*/
#if WIN32
#pragma warning (disable:4786)
#endif
#include <iostream>
#include <string>
#include <iomanip>
#include <vector>
#include <algorithm>
using namespace std;
#define MAX_LINE_LEN 60
void main ()
{
int count = 0;
string filename;
vector<string> flist;
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)
break;
/*
| 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
same result.
*/
cout.fill(' ');
max_len = 0;
while (count--)
{
cin >> filename;
if (filename.length() > max_len)
max_len = filename.length();
flist.push_back(filename);
}
/*
| 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);
++items_per_line;
/*
| 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)
++row_count;
sort(flist.begin(),flist.end());
/*
| 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[0]
| 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.setf(ios::left);
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;
else
cout << " " << setw(max_len) << flist[findex];
}
cout << endl;
}
/*
| Flush the vector and prepare for a new file list.
*/
flist.clear();
}
}[/cpp][cpp][/cpp]
/* @JUDGE_ID: 23756AW 400 C++ "IO Manipulators and Sorted Vector" */
/*
PROBLEM_ID: 400
SYNOPSIS:
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
filenames).
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.
CODE NOTES;
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
manipulators.
SOLUTION NOTES:
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)]
KNOWN ISSUES:
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.
AUTHOR NOTES:
Scott Lane
If you have any problems with this program or want an explanation about the
code feel free to email me at scolane@comcast.net.
*/
#if WIN32
#pragma warning (disable:4786)
#endif
#include <iostream>
#include <string>
#include <iomanip>
#include <vector>
#include <algorithm>
using namespace std;
#define MAX_LINE_LEN 60
void main ()
{
int count = 0;
string filename;
vector<string> flist;
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)
break;
/*
| 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
same result.
*/
cout.fill(' ');
max_len = 0;
while (count--)
{
cin >> filename;
if (filename.length() > max_len)
max_len = filename.length();
flist.push_back(filename);
}
/*
| 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);
++items_per_line;
/*
| 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)
++row_count;
sort(flist.begin(),flist.end());
/*
| 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[0]
| 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.setf(ios::left);
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;
else
cout << " " << setw(max_len) << flist[findex];
}
cout << endl;
}
/*
| Flush the vector and prepare for a new file list.
*/
flist.clear();
}
}[/cpp][cpp][/cpp]
400(calculation)
[c]
i cannot calculate the row and columns needed.
someone help on this matter.[/c]
i cannot calculate the row and columns needed.
someone help on this matter.[/c]
Problems on problem 400 (Unix ls)
Ok, forget this post.. I was just too stupid
PB 400 > UNIX LS | WA
I got wa for this problem ! Could anyone try to explain to me where the matter is ?? Thanks a lot..
[c]
#include <stdio.h>
#include <stdlib.h>
int compare(char*a,char*b)
{
int i=0;
while (a==b)
{
i++;
}
return(a-b);
}
void space(char*tab,int len)
{
int i;
printf("%s", tab);
for (i=strlen(tab);i<len;i++) printf(" ");
}
int main()
{
unsigned int num,i,max,num_row,tmp,num_col;
char files[100][61];
while (scanf("%u",&num)==1)
{
max=1;
num_row=0;
for (i=0;i<num;i++)
{
scanf("%s", files);
if (strlen(files)>max) max=strlen(files);
}
qsort(files,num,61,compare);
do
{
num_row++;
tmp=0;
for(i=0;i<num-num_row;i+=num_row)
{
tmp+=(max+2);
}
tmp+=max;
} while (tmp>60);
printf("------------------------------------------------------------\n");
for (i=0;i<num_row;i++)
{
num_col=num/num_row;
if (num%num_row!=0) num_col++;
for (tmp=0;tmp<num_col-1;tmp++)
{
if (i+tmp*num_row<num)
{
space(files[i+tmp*num_row],max+2);
}
}
space(files[i+tmp*num_row],max);
printf("\n");
}
}
return 0;
}[/c]
[c]
#include <stdio.h>
#include <stdlib.h>
int compare(char*a,char*b)
{
int i=0;
while (a==b)
{
i++;
}
return(a-b);
}
void space(char*tab,int len)
{
int i;
printf("%s", tab);
for (i=strlen(tab);i<len;i++) printf(" ");
}
int main()
{
unsigned int num,i,max,num_row,tmp,num_col;
char files[100][61];
while (scanf("%u",&num)==1)
{
max=1;
num_row=0;
for (i=0;i<num;i++)
{
scanf("%s", files);
if (strlen(files)>max) max=strlen(files);
}
qsort(files,num,61,compare);
do
{
num_row++;
tmp=0;
for(i=0;i<num-num_row;i+=num_row)
{
tmp+=(max+2);
}
tmp+=max;
} while (tmp>60);
printf("------------------------------------------------------------\n");
for (i=0;i<num_row;i++)
{
num_col=num/num_row;
if (num%num_row!=0) num_col++;
for (tmp=0;tmp<num_col-1;tmp++)
{
if (i+tmp*num_row<num)
{
space(files[i+tmp*num_row],max+2);
}
}
space(files[i+tmp*num_row],max);
printf("\n");
}
}
return 0;
}[/c]
-
- Guru
- Posts: 834
- Joined: Wed May 29, 2002 4:11 pm
- Location: Wroclaw, Poland
- Contact:
400 unix is WA
looked easy sounded easy but WA...
any trick here??
I'll send my source code or post it here if it's
necessary, although I prefer sending my source
code to anyone who wants to help
any trick here??
I'll send my source code or post it here if it's
necessary, although I prefer sending my source
code to anyone who wants to help
-
- New poster
- Posts: 19
- Joined: Sun Aug 17, 2003 10:40 pm
I'm using C language.
I tried to looked back in previous post (waaay back),
apparently someone already posted AC source code
here, he use some formula to indicated terminating condition.
I haven't tried that, but in my source code everytime I print
I increment the counter and I check if counter==inputsize
then break the loop. but it gave me WA
I tried to looked back in previous post (waaay back),
apparently someone already posted AC source code
here, he use some formula to indicated terminating condition.
I haven't tried that, but in my source code everytime I print
I increment the counter and I check if counter==inputsize
then break the loop. but it gave me WA