PTA 做题反馈
PTA 题解合集!
1.打印沙漏
题目传送门:link
题面很简单,就是要求打印出一个形如沙漏的符号图形,值得注意的是,具体是什么符号是输入定义的,不要先入为主认为只能是 *
。
考虑取半个沙漏即一个三角形来看,可以发现对于一个三角形来说,每层的符号数构成一个等差数列,根据数学知识,设三角形的高为 h
,需要的符号数为 sum
,则有 sum = (1 + 2 * h - 1) * h / 2
,由于有两个这样的三角形又可化简得 sum = 2 * h * h
,由于重复计算,又需要减一,综上可得 sum = 2 * h * h - 1
, 进行恒等变换又可解得 h = sqrt( ( sum + 1 ) / 2 )
。
这便是唯一的难点,当然,每一层的空格数与符号数之和恒为定值,这是显然的。
代码:
#include <bits/stdc++.h>
using namespace std;
int n, h;
char c;
void solve1(){
for(int i = h; i >= 1; i--){
for(int j = 1; j <= h - i; j++) // 通过数学归纳法,可以得到每一层的空格数等于层数-1;
cout << " ";
for(int j = 1; j <= 2*i-1; j++)
cout << c;
cout << endl;
}
return;
}
void solve2(){
for(int i = 2; i <= h; i++){ // 从第二个开始,不要重复计算
for(int j = 1; j <= h-i; j++)
cout << " ";
for(int j = 1; j <= 2*i-1; j++)
cout << c;
cout << endl;
}
return;
}
int main(){
scanf("%d %c", &n, &c);
h = sqrt((n+1)/2); // 这便是之前提到的难点,
solve1(); // 上半部分
solve2(); // 下半部分
cout << n - (2 * h * h - 1) << endl;
return 0;
}
2. 念数字
题目传送门 : link
这道题真的很简单,但却反应出了我的一个知识漏洞:string
类型数组里的元素每个都是 字符串 类型,直接当做数组下标会出错。原因:会对应它的ASCLL 码。
直接看代码:
#include <bits/stdc++.h>
using namespace std;
string py[] = {"ling", "yi", "er", "san", "si", "wu", "liu", "qi", "ba", "jiu"};
inline void fast_read(){
std::ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
return;
}
string str;
int main(){
fast_read();
cin >> str;
if(str[0] == '-'){
cout << "fu" << " ";
for(int i = 1; i <= str.length(); i++){
cout << py[str[i]-'0']; // 没错就是这里,如果打成 cout << py[str[i]] 循环会炸。
if( i >= str.length()-1 ){
break;
}
cout << " ";
}
} else {
for(int i = 0; i <= str.length(); i++){
cout << py[str[i]-'0'];
if( i == str.length()-1 ) break;
cout << " ";
}
}
return 0;
}
顺带一提,这题会卡你格式,即不能有多余空格。
3. 求整数段和
题目传送门: link
这题也比较水,值得注意的是一个知识点,字符宽度与向左 / 右对齐。
直接用这个题给例子吧,看代码可以懂。
#include <bits/stdc++.h>
using namespace std;
int a[105], n, m, sum;
int main(){
scanf("%d%d", &n, &m);
for(int i = n, j = 1; i <= m; i++, j++){
sum += i, a[j] = i;
}
for(int i = 1; i <= m-n+1; i++){
printf("%5d", a[i]); // 就是在这里
if( i % 5 == 0 && m - n != 4) cout << endl;
}
printf("\nSum = %d", sum);
return 0;
}
向左对齐:printf("%-nd", xx)
向右对齐:printf("%nd", xx)
其中 n
为字符宽度,xx为变量。