L1-039 古风排版 (20 分)
中国的古人写文字,是从右向左竖向排版的。本题就请你编写程序,把一段文字按古风排版。
输入格式:
输入在第一行给出一个正整数N(<100),是每一列的字符数。第二行给出一个长度不超过1000的非空字符串,以回车结束。
输出格式:
按古风格式排版给定的字符串,每列N个字符(除了最后一列可能不足N个)。
输入样例:
4
This is a test case
输出样例:
asa T
st ih
e tsi
ce s
【思路】
本题利用一个二维char数组装字符,然后用递归的思想,把字符装进去就可以了。
设paiban函数,paiban(int index, int c) 表示当前排到第index个字符,排到第c列。
那么我们利用数学知识,求出一开始的排版列号col,故一开始为paiban(0, col)
那么要完成paiban(0, col)这个函数,我们就必须先把第col列的字符给装进去,再调用paiban(n, col - 1)函数就可以了,形成递归。
递归方程:paiban(0, col) = 把第col列装好 + paiban(n, col - 1)
主要坑点:字符串读取进去之后,末尾都是带着’\0’的,这个\0字符与空格在输出时没什么区别,所以很容易坑到你。
我们需要把字符串末尾的空间全部填充成空格就没问题了
AC代码:
#include<iostream>
using namespace std;
const int maxn = 1002;
char a[maxn][maxn];
int n;
string s;
int len;
int row, col;
int tag = 0;
void paiban(int index, int c) //开始排第index个字符,目前在c列
{
int j = 1; //行号
int i = 0;
//每次排n个字符
for(i = index;i < index + n && i < len;i++) //i < len确保不超界
{
a[j][c] = s[i]; //排字符
j++;
}
if(i < len)
{
paiban(i, c - 1);
}
else //如果i >= len,防止末尾\0字符
{
if(tag == 0)
{
for(int k = j;k <= row;k++)
{
a[k][c] = ' '; //坑点:二维数组下面全都要置成空格
}
}
}
}
int main()
{
cin >> n; //n > 0
getchar(); //有必要读掉回车
getline(cin, s);
len = s.size();
row = n;
if(len % n == 0)
{
col = len / n;
tag = 1;
}
else
{
col = (len / n) + 1;
}
paiban(0, col); //开始排第0个字符,对应的是数组中的第col列开始
//输出数组即可
for(int i = 1;i <= row;i++)
{
for(int j = 1;j <= col;j++)
{
cout << a[i][j];
}
cout << endl;
}
return 0;
}