欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

算法竞赛 例题5-8 Unix ls命令(Unix Is,UVa 400)

程序员文章站 2022-07-13 17:48:24
...

题目要求:
输入正整数N以及N个文件名,排序后按列优先的方式左对齐输出。假设最长文件名有M个字符,则最右列有M个字符,其他列都是M+2个字符,不够的则在末尾补空格字符。要求输出的每行的总字符数不超过60,且行数最小。

求行数和列数:
由于每行最多60个字符,输入的文件名最长字符为M个,最右列是M个字符,其余的每列都是M+2个字符,所以列数为cols=(60-M)/(M+2)+1;行数是总的个数除以列数+1,rows=(n-1)/cols+1;
思路:
给输入的文件名排序,存在数组里,如果是横向输出,可以跳着输出,例如列为4的时候,先输出filenames[0],然后输出filenames[4],filenames[8]…如果是纵向输出,需要两个for循环,先for循环列,里边嵌套for循环行。

C++代码

#include <iostream>
#include <string>
#include <algorithm>
using namespace std;

const int maxcol=60;//每行最多60个字符
const int maxn=100+5;
string filenames[maxn];//文件名数组

//输出字符s,长度不足len时,用字符extra补齐
void print(const string& s,int len,char extra){
    cout<<s;
    for(int i=0;i<len-s.length();i++){
        cout<<extra;
    }
}//s 文件名,len是M+2,len-s.length()是需要输出的空格,extra是符号。

int main()
{
    int n;
    while(cin>>n){
        int M=0;
        for(int i=0;i<n;i++){
            cin>>filenames[i];
            M=max(M,(int)filenames[i].length());//最长文件名
        }
        //计算列数cols和行数rows
        int cols=(maxcol-M)/(M+2)+1;
        int rows=(n-1)/cols+1;
        print("",60,'-');
        cout<<"\n";
        sort(filenames,filenames+n);
        for(int r=0;r<rows;r++){
            for(int c=0;c<cols;c++){
                int a=c*rows+r;
                if(a<n)
                    print(filenames[a],c==cols-1?M:M+2,' ');
                    //若为最后一列是M个字符,若不是最后一列是M+2个字符
            }
            cout<<"\n";
        }
    }

    return 0;
}

结果:
算法竞赛 例题5-8 Unix ls命令(Unix Is,UVa 400)

错误:最后出来一点小问题,最后一列还是按照M+2个字符输出,如果把cols-1改为cols-2就可以了,但是不太理解为什么?哪位大佬看到,帮忙解答一下, 谢谢!

相关标签: 算法竞赛例题