PAT_刷题心得

本博客记录一些关于我刷pat题目出现的一些心得(或错误)。

PAT_A1046(错误是段错误)

下面是代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include<cstdio>
#include<iostream>
using namespace std;
int d[100005];
int ans[2][100005];//应改为:int ans[100005][2]
int sum(int a,int b,int t) {
int sum = 0;
while (a % (t + 1) != b) {
sum += d[a];
a = a % t + 1;
}
return sum;
}
int main() {
int t, r;
int p1, p2;
scanf("%d", &t);
for (int i = 1;i <= t; i++) {
scanf("%d", &d[i]);
}
cin >> r;
for (int i = 0;i < r; i++) {
scanf("%d%d", &p1, &p2);
ans[i][0] = sum(p1, p2, t);
ans[i][1] = sum(p2, p1, t);
}
for (int i = 0; i < r; i++) {
if (ans[i][0] > ans[i][1]) {
printf("%d", ans[i][1]);
}
else {
printf("%d", ans[i][0]);
}
if (i < r - 1) {
cout << endl;
}
}
return 0;
}

错误原因:这里定义出错导致访问的内存超出了系统所给这个程序的内存空间。其实就是这里定义错误,导致最后访问了不该访问的内容。

Ps:虽然后来又超时了。。。


PAT_A1065

下面是代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include<cstdio>
#include<iostream>
using namespace std;
int main(){
int t, ans[11] = {0};
long long a, b, c, s;
cin >> t;
for (int i = 1;i < t + 1; i++) {
scanf("%lld%lld%lld", &a, &b, &c);
s = a + b;//错误从这里开始
if (a > 0 && b > 0 && s < 0)
ans[i] = 1;
else if(a < 0 && b < 0 & s >= 0)
ans[i] = 0;//错误到这里结束
else if (s > c) {
ans[i] = 1;
}
}
for (int i = 1; i < t+1; i++) {
printf("Case #%d: %s", i, ans[i] == 1 ? "true" : "false");
if (i < t)
printf("\n");
}
return 0;
}

错误原因:没有考虑到正负溢出的情况。(看了晴神笔记才知道的,原来正负溢出会这样嘛。。。)

---2019.10.3

PAT_B1010

下面是代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include<cstdio>
#include<iostream>
using namespace std;
int main() {
int a, b, t = 0;
while (cin >> a >> b) { //输入直到文件尾
if (b != 0) {
if (t == 1)cout << ' ';
cout << a * b << " " << b - 1;
t = 1;
}
}if (!t) {
cout << "0 0";
}
return 0;
}

错误原因:之前还没有遇到过不告诉运行几次的代码,所以无法确定运行代码次数,而c里是scanf() !=EOF 来表达到达文件尾时退出,而c++里是>>操作了一个重载函数,它到达EOF的返回值时返回0,所以就可以结束循环了。


PAT_B1041

错误原因:其实也没有错,所以就没有代码啦。就是有一个可以优化的点,索引的时候可以把需要索引的值作为数组的下标,这样索引的时候就直接用下标就好啦。(当然索引值一定要是确定的)

---2019.10.4

PAT_B1028

心得:其实有时候索引的时候不需要把所有记录全部记录下来,直接保留需要用到的就好。

比较日期的方法:先比较年如果年,年一样,再比较月,月一样再比较日(年月不一样就直接结束比较了);

---2019.10.5

PAT_B1027 打印沙漏

这种画图题,不要傻乎乎的因为左边要添加空格,就把图形右边也加上了空格。

---2019.10.9

分享两个进制转换的模板

1、将 P 进制数转换为十进制数 y

1
2
3
4
5
6
int y = 0, product = 1;
while(x != 0){
y = y + (x % 10) * product;
x = x / 10;
product = product * p;
}

2、将 10 进制数 y 转换为 q 进制数 z 。

1
2
3
4
5
6
7
int z[40], num = 0;
do{
z[num++] = y % q;
y = y / q;
}while(y != 0);

do while的原因是预防了 y = 0的情况,转换完之后需要逆向输出。

PAT_B1021

当需要输入很多位时,可以用字符数组来输入。

可以用str[i] - ‘0’(或者A..)来检索。

---2019.10.11

PAT_A1001

代码就不列出来了,就是当使用while(){}的时候,比如说”i!=0”的时候,容易漏判 i==0 的情况,解决方法有两种:

1、用do{}while();

2、特判”0”;

Ps:好多天没刷题了,得赶紧刷了。

---2019.10.21

PAT_A1025

这是一道很常规的排序题,主要就是用结构体和sort来排序,但是容易出错的地方有他们的id,有时候要用字符串来存,有时候要用整型。

例如这道题柳神是用的长整形,算法笔记用的是字符型,而我用长整型就有最后一个测试点过不去,用字符型就可以,因为vector我还没学过,到时候再来看这道题吧。

看了一下,这个题最后要用

1
printf("%013lld ", a[i].id);

这个形式输出,才可以AC,不过题目规定的是13位id,按道理来说直接输出也是没有问题的才对。。。。。我懂了,如果id前面都是0的话,最后只能输出最后的几位,前面的 0 输出不了。。。。。

PAT_A1055

这道题如果不用 scanf 或者 printf 可能会超时。。

---2019.10.27

PAT_A1080

这道题虽然ac了,但是花了很长时间,所以再实现一边算法笔记里的算法。

---2019.10.28

PAT_A_1095

这道题虽然最后AC了,不过时间也做了很久,做的真不容易,一开始题目意思理解错,后来连算法笔记都开始用c++了,我用c语言做的实在是太不容易了,一堆临时变量,写完就看不懂了,不说了去学c++了。296ms过的关就差4ms,到时候学完c++,再回来看看算法笔记的算法吧。

---2019.10.29

PAT_A_1060

又是好几天没有刷PAT了。。。

我永远讨厌科学计数法.jpg

以后看问题还是要看本质,从手写的方式先实现一次再说。

PAT_A_1100

1
2
3
string str;
getline(cin, str);
//这样可以强行输入一行字符串,例如有空格的时候。

有时候,当数量比较少的时候,用枚举法也不是一个坏的选择。

---2019.11.06

PAT_A_1054

这不是一道难题,但是我用来新学的用scanf来输入string结果出现了问题,scanf(cin,&str[0]);我用了这个方法以后,我的map不管是什么字符串他都能找到,可是map里根本就没有。所以以后还是老老实实用cin吧。

---2019.11.07
PAT_A_1071 算法笔记上的这道题的算法是查询单词的典范,十分值得回来看看。

PAT_A_1022

在scanf或者cin之后用getline的时候千万不要忘记用getchar()来吃回车。
这道题题目很简单,我虽然AC了但是感觉并没有深入的理解题目的意思,算法笔记上的方法很新奇,既然我们最后要输出最后查询的ID,那我们为什么不可以在输入的时候,就把这个事情做好呢。我的思路是用id做跳板,来寻找需要的内容,然后再返回ID。算法笔记在输入的时候就把每个属性,所带的ID放到一起了,到最后不就直接可以遍历该属性的集合输出答案了吗。这还是散列的思想发需要查询的内容,直接放成下标,选择下标的时候,速度会快很多。而且还可以用map的find函数寻找,不用自己遍历。

还有寻找关键词的方法,我当时是想到可不可以一个一个输入关键词,可是我又想怎么判断这一行有没有输完呢,算法笔记给了一个很好的方法,就是

1
char c = getchar();

通过判断 c 是回车还是“ ”来判断是否到语句尾,十分聪明。

PAT_A_1092

如果是要统字符的个数,为什么不直接int[300]呢,(ascill码 == 256) == true;

---2019.11.08