题目

废话:

啊,本蒟弱搜了好多题解,但是对我这种蒟蒻来说感觉都不太友好,有的直接贴了紫书的代码,注释都没写。这道题本蒟弱想了好久,看到网上大佬说水题。。。(我太弱了)于是本蒟决定写个详解来帮助刚入门的小伙伴,思路参考紫书,代码略有不同

题意:

输入正整数n以及n个文件名,按字典序排列后,按列优先输出。假设最长长文件名有M字符,则最右列有M字符,其他列有M+2个字符,其中每行最多60个字符

人话:

  1. 按列优先输出:比如有1~10个数字,要求五行两列按列优先输出,则是:
  2. 最右列M个字符:
    最右列的宽度是M个字符,如果不够,则用空格补齐。比如输入的最长文件名长度为5个字符,则最右列宽5个字符,其余列宽5+2个字符,不够空格补齐

思路:

  1. 首先这道题需要将输入的字符串按字典序排个序,我们利 用string filename[105],这个二维数组存储字符串,filename[i],代表一个字符串

  2. 排序就利用sort对string 二维数组排序
    sort(filename,filename+n);

  3. 在输入的时候求出最长文件名的长度M

  4. 计算输出有多少行和列:
    列:因为最后一行占M个字符宽度,每一行有最多60个字符60-M就是其余列总共占的宽度,由于其余列各占M+2的宽度则(60-M)/(M+2)就是除去最后一列有多少列,再加一个1就是全部的列数,1代表最后一列 则cols = (60-M)/(M+2)+1
    行:
    rows = n/cols + (n%cols!=0?1:0);
    //,如果不能够整除,则余数也要占一行,所以要加1

  5. 还需要在输出的时候判断即将访问的数组下标,是否小于n,因为对于某一行不够满列的情况,比如输入只有一个单词,长度为10,利用刚才的计算方法cols = (60-10)/(10+2)+1 = 5,但是只有一列,所以需要判断

  6. 如何按照列优先输出:idx = i + j*rows
    例如数字1~20,
    对于数字1 idx= 0 + 0x5,刚好是1所在的下标0
    数字 6 idx=0 + 1x5=5,也是数字6所在的下标

x

 for(int i=0;i<rows;i++)//行
        {
            for(int j=0;j<cols;j++)//列
            {
                 int idx = i + j*rows;//下标
                 //一定要注意这里不要越界了,不能超过输入的文件个数
                if(idx<n)  print(filename[idx],j==cols-1?M:M+2);
            }
              cout<<endl;
        }

AC代码:

#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
const int maxn = 105;

void print(const string &s,int len)//字符串s,和它需要占的宽度
{
    cout<<s;
    //这里不需要if语句,
    //如果条件满足这个循环会自动执行,不满足不会执行
    for(int i=0;i<len-(int)s.size();i++)
        cout<<" ";

}
int main()
{
	int n;
	while(cin>>n)
    {
        //filename[i]代表一个文件名字符串
        string filename[maxn];
        int M = 0;
        for(int i=0;i<n;i++)
        {
            cin>>filename[i];
            //利用迭代法求这一轮输入的文件名的最长长度
            M = max(M,(int)filename[i].size());
        }
        sort(filename,filename+n);//对string类型的排序
        int rows,cols;//行列
        //首先求出列数,每行的列数是相同的
        //每一行有60个字符,除去最后一列外每一列的宽度为M+2
        //所以每一行有(60-M)/(M+2) + 1列,加1代表加上最后一列
        cols = (60-M)/(M+2) + 1;//列
        //行,如果不能够整除,则余数也要占一行,所以要加1
        rows = n/cols + (n%cols!=0?1:0);
        for(int i=0;i<60;i++) printf("-");
        printf("\n");
        for(int i=0;i<rows;i++)//行
        {
            for(int j=0;j<cols;j++)//列
            {
                 int idx = i + j*rows;//下标
                 //一定要注意这里不要越界了,不能超过输入的文件个数
                if(idx<n)  print(filename[idx],j==cols-1?M:M+2);
            }
              cout<<endl;
        }

        }
	return 0;
}

这道题理解题意很重要,本蒟弱困了好久,蒟蒻大军们,冲啊!