L1-039. 古风排版
中国的古人写文字,是从右向左竖向排版的。本题就请你编写程序,把一段文字按古风排版。
输入格式:
输入在第一行给出一个正整数N(<100),是每一列的字符数。第二行给出一个长度不超过1000的非空字符串,以回车结束。
输出格式:
按古风格式排版给定的字符串,每列N个字符(除了最后一列可能不足N个)
输入样例:4 This is a test case输出样例:
asa T st ih e tsi ce s
想法:这个题本身其实并不难,只要会用字符串操作的基本上都没问题。但是,因为我身边就有很多因为对字符串操作不熟的而在比赛中甚至是赛后都WA的死的人。现在我的主要目的是点出那些坑。
首先,是AC代码。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
char Cmap[1005][1005];
int main()
{
int n,m;
char s[1005];
cin >> n;
getchar(); //用这个来接收空格
gets(s);
int len = strlen(s);
m = len/n;
if(len%n != 0) m++;
int i = 0;
for(int k = m-1; k >= 0; k--){
for(int j = 0; j < n; j++){
if(i < len)
Cmap[j][k] = s[i++];
else
Cmap[j][k] = ' '; //当长度超过len时直接赋值空格。
}
}
for(int j = 0; j < n; j++){ // 最后输出。
for(int k = 0; k < m; k++)
cout << Cmap[j][k];
cout << endl;
}
return 0;
}
这个代码的思路很好理解,(而且做法也很烂,我个人感觉应该是可以直接输出答案的。)下来就就是点一下几个坑点。为了方便辨认,修改部分已注明。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
char Cmap[1005][1005];
int main()
{
int n,m;
char s[1005];
//有修改
for(int j = 0; j < 1005; j++){
for(int k = 0; k < 1005; k++)
Cmap[j][k] = '.';
s[j] = '.';
}
cin >> n;
getchar(); //用这个来接收空格
gets(s);
int len = strlen(s);
m = len/n;
if(len%n != 0) m++;
int i = 0;
for(int k = m-1; k >= 0; k--){
for(int j = 0; j < n; j++){
//有修改
Cmap[j][k] = s[i++];
}
}
for(int j = 0; j < n; j++){ // 最后输出。
for(int k = 0; k < m; k++)
cout << Cmap[j][k];
cout << endl;
}
return 0;
}
与上面做法不同的就是对最后空格的处理。在上面是第一份代码中是赋值空格,在这一份中是刚开始就初始化为空格。从逻辑上讲并没错。但是,在真正运行的过程中则不是。现在我初始化成的空格改成‘.’,我们在来输出结果。
修改部分的代码如下图:
修改部分代码
修改后的输出结果:
现在我们可以发现在字符5下面的出现的是空格而不是我们初始化的‘.’。之所以会出现这种原因是因为我们在对一个字符串进行输入时,字符串的末尾是‘\0’,以图中的输入为例。从第一个字符到第一千个字符依次是:‘1’,‘2’,‘3’,‘4’,‘5’,‘\0’,'.','.','.'........(此后省略。)所以,在字符5下面的输出其实并不是空格而是‘\0’,因为,在此题中输出结果的末尾是补空格。所以,我们看不错误。但是,对于评测机判定时的判定结果是‘\0’,这也就是使我们WA了一发。
会出现这种错误的原因说到底还是因为自己对字符串方面的内容不熟才会出现的。但是,这种情况应该只会出现在刚入坑的萌新中。不得不说PAT上的简单题,考的就是C语言的基础知识。对于我们语法上的锻炼还是很有帮助的。