我开始写这篇笔记时,2019年研究生考试的初试成绩已经出来了,我的分数还算理想,但是由于同届选手很强,目前排名并不理想,看来在复试方面还得更加努力,争取逆袭了。
在part1中我说过这份笔记将主要分两个部分。本篇笔记即为part2。内容为我刷PAT的题目得出的经验以及一些思考。
希望能顺利的通过复试(如果能进复试的话...)
1.1002 写出这个数(https://pintia.cn/problem-sets/994805260223102976/problems/994805324509200384)
#include
#include
#include
using namespace std;
string map[] = {"ling", "yi", "er", "san", "si", "wu", "liu", "qi", "ba", "jiu"};
int main(){
string str1, str2;
cin >> str1;
int all = 0;
for(string::iterator hehe=str1.begin();hehe != str1.end();hehe++){
int a = *hehe - '0';
all += a;
}
stringstream ss;
ss << all;
str2 = ss.str();
int count = 0; //trick
for(string::iterator haha=str2.begin();haha != str2.end();haha++){
if(count != 0)
cout << " ";
count ++;
int a = *haha - '0';
cout << map[a];
}
}
【小结】想说两个东西。一是stringstream,这个主要是用来转换类型的(好用,详见https://www.cnblogs.com/hujunzheng/p/5042068.html);二个是如何避免最后一个空格不被输出,加一个count即可。
2.1004 成绩排名(https://pintia.cn/problem-sets/994805260223102976/problems/994805321640296448)
#include
#include
using namespace std;
struct Student{
int grade;
string id;
string name;
}temp, Max, Min;
int main(){
Max.grade = -1;
Min.grade = 100;
int T;
cin >> T;
while(T--){
cin >> temp.name >> temp.id >> temp.grade;
if(temp.grade > Max.grade)
Max = temp;
if(temp.grade < Min.grade)
Min = temp;
}
cout << Max.name << " " << Max.id << endl;
cout << Min.name << " " << Min.id;
return 0;
}
【小结】本题不难,记录一点:我之前写结构体一直写的是typedef struct,其实在C++里完全可以采用以上这种更为简洁的写法。
3.1036 跟奥巴马一起编程(https://pintia.cn/problem-sets/994805260223102976/problems/994805285812551680)
【小结】本题不难,不贴代码了,就记一点:关于这个四舍五入要注意,比如对a四舍五入就要写成a/2+a%2。
4.1038 统计同成绩学生(https://pintia.cn/problem-sets/994805260223102976/problems/994805284092887040)
#include
int main(){
int score[1001] = {0};
int n;
scanf("%d", &n);
for(int i=0;i
【小结】最开始做这道题一个点比较懵,就是不知道怎么分别读入10 20 30这样的数字,事实上只要想以上代码一样分别写scanf即可,我确实是之前刷题太少,继续加油。
5.1014 福尔摩斯的约会(https://pintia.cn/problem-sets/994805260223102976/problems/994805308755394560)
#include
#include
#include
using namespace std;
string week[] = {" ", "MON", "TUE", "WED", "THU", "FRI", "SAT", "SUN"};
int main(){
string str1, str2, str3, str4;
cin >> str1;
cin >> str2;
string d;
int h = 0;
int len = min(str1.length(), str2.length());
for(int i=0,count=1; i= 'A'){
count++;
int t = str1[i] - 'A' + 1;
d = week[t];
}
if(str1[i]==str2[i] && count==2){
if(str1[i]<10 && str1[i]>=0)
h = str1[i];
else if(str1[i]<='N' && str1[i] >= 'A'){
int t = str1[i] - 'A' + 1;
h = t + 9;
}
}
}
cin >> str3;
cin >> str4;
int len_1 = min(str3.length(), str4.length());
int m = 0;
for(int i=0; i= 97 && str3[i] <= 122){
m = i;
break;
}else if(str3[i]==str4[i] && str3[i] >= 65 && str3[i] <= 90){
m = i;
break;
}
}
if(m > 9)
cout << d << " " << h << ":" << m <
【小结】本题这样提交上去是部分正确,目前我还不知道哪里不对,第二轮再来看看。
6. 1028 人口普查(https://pintia.cn/problem-sets/994805260223102976/problems/994805293282607104)
【小结】本题不难,不贴代码了。记一个点:当本题没有一个有效数据时,若不特殊处理,输出0后会有空格,则会导致格式错误,所以必须要在最后特殊处理一下。
7.1013 数素数 (https://pintia.cn/problem-sets/994805260223102976/problems/994805309963354112)
#include
#include
using namespace std;
bool isPrime(int n){
if(n <= 1)
return false;
int sqr = (int)sqrt(1.0*n);
for(int i=2; i<= sqr; i++)
if(n % i == 0)
return false;
return true;
}
int prime[10001], pNum = 0;//存素数
void find_prime(){
for(int i=1; i<1000001; i++){
if(isPrime(i) == true)
prime[pNum++] = i;
if(pNum == 10000)
break;
}
}
int main(){
int m, n;
cin >> m >> n;
find_prime();
int left = prime[m-1];
int right = prime[n-1];
for(int i=0, count=0; i=left && prime[i]<=right){
count++;
if(count % 10 == 1)
cout << prime[i];
else if(count % 10 == 0)
cout << endl;
else
cout << " " << prime[i];
}
}
}
【小结】又出现了一道部分正确的题目,目前也还没看出来哪里不对。这里关于如何在输出最后不加空格做个记录:可以先输出第一个数,然后在以后的每次输出的前面加空格,从而就可避免上述问题。
8. 1009 说反话(https://pintia.cn/problem-sets/994805260223102976/problems/994805314941992960)
#include
#include
#include
using namespace std;
int main(){
vector vi;
string t;
getline(cin, t);
string re;//存放一个个单词
for(int i=0; i=0; i--){
if(flag == 0){
cout << vi[i];
flag++;
}
else
cout << " " <
【小结】通过这道题我对于vector, string的使用更加熟悉了。这里要提两点:一是若想将一个字符加入string,要用push_back(),其它几个都会失败,原因是push_back(i)中的i是一个元素,而其他函数普遍是添加字符串的;二是string的输入问题,由于单纯的cin输入遇到空格会停止,所以这里要有getline来输入一整行。
9.1091 N-自守数(https://pintia.cn/problem-sets/994805260223102976/problems/1071785664454127616)
#include
#include
#include
#include
using namespace std;
int zishou(int n, int len){
for(int i=1; i<10; i++){
int r = i*n*n;
if(r % (int)pow(10.0, len) == n)
return i;
}
return -1;
}
int main(){
int T;
cin >> T;
while(T--){
string a;
cin >> a;
int len = a.size();
istringstream aa(a);
int i;
aa >> i;
int res = zishou(i, len);
if(res == -1)
cout << "No" << endl;
else
cout << res << " " << res*i*i << endl;
}
}
【小结】两个点:一是pow()这个函数,我用的VS2008对数学函数的参数检查更为严格,pow(2, 45)会引起一个错误提示如下:
error C2668: “pow”: 对重载函数的调用不明确......其解决方案是当试图匹配参数列表“(int,int)”时,使用为pow(2.0, 45);另一点依然是类型转换,本题中我将字符串转化为了整型。(ps:我在part1中有一个类型转换的专题)
10.1026 程序运行时间(https://pintia.cn/problem-sets/994805260223102976/problems/994805295203598336)
#include
using namespace std;
typedef long long ll;
int main(){
double begin,end;
while(cin >> begin >> end){
ll time = double((end-begin)/100)+0.5;
int h = time / 3600;
int m = time % 3600 / 60;
int s = time % 60;
printf("%02d:%02d:%02d\n", h, m, s);
}
}
【小结】这个题目我之前用cout输出花了很多时间,然而却忘了printf的自动补齐功能,如上;另外while(cin >> begin >> end)的写法也值得收藏。
11.1005 继续(3n+1)猜想(https://pintia.cn/problem-sets/994805260223102976/problems/994805320306507776)
#include
#include
using namespace std;
int num[10001] = {0};
int save[101] = {0};
bool com(int a, int b){
return a > b;
}
int main(){
int T;
cin >> T;
while(T--){
int a;
cin >> a;
if(num[a] == 0)
num[a] = 1;
while(a != 1){
if(a % 2 == 0)
a /= 2;
else
a = (a*3 + 1)/2;
num[a] = 2;
}
}
int count = 0;
for(int i=0; i<10001; i++)
if(num[i] == 1)
save[count++] = i;
sort(save, save+count, com);
for(int i=0, flag=0; i
【小结】这道题主要是思路比较重要,将各个数字当作数组下标来处理是个非常好的思路。
12.1010 一元多项式求导 (https://pintia.cn/problem-sets/994805260223102976/problems/994805313708867584)
#include
#include
using namespace std;
void reverse(int a[], int range_a, int range_b){ //对一个数组进行逆序处理
for(int i=0; i<=(range_b-range_a)/2; i++)
swap(a[range_a+i], a[range_b-i]);
}
int main(){
int n, m_1, pos=0;
int A[101] = {0};
cin >> n >> m_1;
int m = m_1 % n;
int n_1 = n;
while(n_1--){
int value;
cin >> value;
A[pos++] = value;
}
if(m != 0){
reverse(A, 0, n-m-1);
reverse(A, n-m, n-1);
reverse(A, 0, n-1);
}
for(int i=0, flag=0; i
【小结】这道题主要就是注意一下两个特殊情况:一是m为0时,二是m超过n时。
13.1012 数字分类 (https://pintia.cn/problem-sets/994805260223102976/problems/994805311146147840)
【小结】这道题有个坑,不处理会过不了最后一个点。那就是对于A2,运算之后的结果是可能为0的,所以要特别处理
14.1027 打印沙漏(https://pintia.cn/problem-sets/994805260223102976/problems/994805294251491328)
【小结】注意题目没有说符号后面有空格!不要想当然!
15.1090 危险品装箱(https://pintia.cn/problem-sets/994805260223102976/problems/1038429484026175488)
#include
#include
【小结】通过这道题知道了两个东西:1.vector可以初始化,这样可以避免每次都分配内存;2.注意 if(h[mp[v[i]][j]] == 1) 这句话,这是这道题比较复杂的情况,但是让我知道map确实很强大。
16.1025 PAT Ranking(https://pintia.cn/problem-sets/994805342720868352/problems/994805474338127872)
#include
#include
using namespace std;
struct Stu{
long long id;
int score;
int final_rank;
int local_id;
int local_rank;
}stu[30010];
bool cmp(Stu a, Stu b){
if(a.score != b.score)
return a.score > b.score;
else
return a.id < b.id;
}
int main(){
int N;
scanf("%d", &N);
int count = 0; //总人数
for(int i=1; i<=N; i++){
int num;
scanf("%d", &num);
for(int j=0; j0 && stu[i].score != stu[i-1].score){
r = i+1;
}
printf("%lld ", stu[i].id);
printf("%d %d %d\n", r, stu[i].local_id, stu[i].local_rank);
}
return 0;
}
【小结】从这道题学到了如果要对学生成绩排名,要先进行排序。然后才能对100 100 99排出 1 1 3这种排名。对了,上面这个代码还有一个点过不了,之后再来看看。
17.最大公约数相关(利用欧几里得算法,亦称辗转相除法)
int gcd(int a, int b){
if(b == 0)
return a;
else
return gcd(b, a % b);
}
18.1083 是否存在相等的差(https://pintia.cn/problem-sets/994805260223102976/problems/994805260780945408)
#include
#include
#include
【小结】本题记录下map逆向遍历的方法,使用reverse_iterator结合rbegin和rend即可。
19.1049 数列的片段和(https://pintia.cn/problem-sets/994805260223102976/problems/994805275792359424)
#include
using namespace std;
int main(){
double ans = 0;
int n;
cin >> n;
double input;
for(int i=0;i
【小结】这道题看似像在找全子集,但实际上可以通过找规律做出来!见下图:
20.1054 求平均值(https://pintia.cn/problem-sets/994805260223102976/problems/994805272659214336)
【小结】这道题很坑!注意若k=1,那么输出为number而不是numbers,读题要仔细!
21.1033 旧键盘打字 (https://pintia.cn/problem-sets/994805260223102976/problems/994805288530460672)
【小结】这道题注意,‘_’是代表空格,也就是说输入的是真的空格,而不是下划线。所以输入要用getline,不能用cin(将空格当作结束符)
22.1095 解码PAT准考证(https://pintia.cn/problem-sets/994805260223102976/problems/1071786104348536832)
【小结】这道题比较复杂,学到了很多东西。记录如下: