宇宙无敌PAT-A不完全考纲

    大家新年快乐!
    最近一直有朋友问我“考研上机怎么准备?”、“马上找工作,想考PAT练练手”等...其实本来刚考完PAT的时候,我是想总结一下各个平台以及教程的所有题目合成一本模板教程。但是我想想吧,这样让大家太偷懒了,不利于大家的智力发展。还是建议大家自己先做一遍,然后对着答案改,然后形成自己的模板比较好(其实是我懒 /(T_T)/~~~)。
    对于考研上机的同学,我的建议是首先扒几道真题做做,看看难度,大概了解题型,然后再有针对性的准备。对于考PAT的同学,不需要刷题,按照此考纲就可以考97分了...剩下3分留给意外...
    其实上机考试一直没有一个明确的范围,刷题更多的一方面其实也是想知道大概考什么。在我准备的时候,其实很多时间都花在“考什么”上,总感觉怎么看都不全面,好像什么都会了但是总是没啥自信就怕考到不会的。可以说在摸清“范围”上花的时间是最多但是也是不得不花的。所以这次整理了一个不完全考纲(没有全部做一遍,完全不了),给大家画画重点,让大家有针对性的准备,同时也可以获得十足的信心。


    由于是主要针对PAT的考纲,所以下面重点说说PAT的脾气。
    PAT-A总共有4题,时间为3小时三四大题 是一题图、一题树的概率较大,偶尔动态规划,贪心算法等。 第二题 一般是STL(map,set,vector为主,偶尔队列,堆栈)。第一题小题(逻辑题,字符串处理,数学,枚举),要么简单,要么读题复杂理解复杂情况不容易想到,但是程序不会太复杂。其他的比如排序、查找、哈希、递归、递推、尺取法、哈夫曼、链表、素数的判断、数学问题、模拟、逻辑什么的,不需要复习,一般都融在题目里,是最基本的,看能力。
    很多人说考PAT要刷题,但是我现身说法其实不用的。我的准备时间大概半个月,准备之前大概三四个月没有写过代码了,大概每天做一套题,最后考了97(emmm有一个点马虎了,死活想不起来函数是怎么拼写的了尴尬),排名84/1041(应该是考97的前几名,大概80个左右考100的)。我简书里面是我从开始准备PAT到考试做过的所有题目,所以你在点击链接的时候会发现我有题没做出来(这个现象在最开始特别严重,后来好多了),所以大家要是看了半天发现我程序没写或者没有全部AC的时候(放心我标注了),请自己查下答案哈~不过要是追求考100的前几名,那估计要刷1个月以上,让自己更熟悉。


所谓的官方考纲

对于PAT乙,考生应具备以下基本能力:

1. 基本的C/C++的代码设计能力,以及相关开发环境的基本调试技巧;

2. 理解并掌握最基本的数据存储结构,即:数组、链表;

3. 理解并熟练编程实现与基本数据结构相关的基础算法,包括递归、排序、查找等;

4. 能够分析算法的时间复杂度、空间复杂度和算法稳定性;

5. 具备问题抽象和建模的初步能力,并能够用所学方法解决实际问题。

对于PAT甲,在达到乙级要求的基础上,还要求:

1. 具有充分的英文阅读理解能力;

2. 理解并掌握基础数据结构,包括:线性表、树、图;

3. 理解并熟练编程实现经典高级算法,包括哈希映射、并查集、最短路径、拓扑排序、关键路径、贪心、深度优先搜索、广度优先搜索、回溯剪枝等;

4. 具备较强的问题抽象和建模能力,能实现对复杂实际问题的模拟求解。

总而言之描述的相当宽泛,你行就你行,你不行就不行....


下面的考纲从最重要的、考试概率最大的开始讲起,用最少的时间得最多的分数。祝大家考一个好成绩!biu~

图论算法★★★★★

     图论算法几乎每年都有,99%会考,剩下1%是出卷老师啊想晃你一下。

搜索算法DFS/BFS★★★★

     假如出题老师手下留情,可能会出图的搜索问题。搜索算法一般以DFS和BFS为主,简单一点就是纯算法,难一点就是加上各种条件和剪枝。无论是在上机考试还是在PAT中,都属于基础题目,不一定出,但是出了你必须会。
     同时需要学会的配套算法还有迭代递归强联通分量连通分量,所以迭代和递归不需要单独训练,可以跟搜索算法同时做练习。一道题目可以分别用DFS和BFS做一遍,加强熟练度。要会统计联通分量的个数。
     经典题目为“走迷宫”、“算水里有几块陆地”之类的题目,必须会做,都是下酒小菜。

练习题:PAT A 1106,PAT A 1103,PAT A 1091,PAT A 1013(统计强联通分量的个数)

最短路径★★★★★

     这是 上机考试 中图论算法最容易考的一点,不考这个考什么(PAT-A考到的可能性没这么大,但是万一考到了也跟尴尬)。
PAT-A最难的会让你输出最短路径,并且加条件,例如若路径相同则输出价格较小的一条,当价格相同时再输出最少时间的一条,最后输出最小值和路径
     所以这一条套路必须会,会一题即可:PAT A 1111

其他练习:PAT A 1003,PAT A 1018,PAT A 1030,PAT A 1087

图论知识★★★★

上机考试 中这个点不经常考,但是在PAT中这个点不难,但是经常考。
图论知识就是让你判断这个图是不是一个怎么样怎么样定义的图,这里面用到的方法其实还是搜索算法,只不过加上条件而已。只不过比较头疼的是题目给你的定义,题目给的定义不一定跟我们学过的离散数学一模一样,但是也是大差不差。所以在做题之前先看一眼中文的定义有个概念会加快读题速度,最后只要注意你理解的定义和题目给的定义有什么区别就行了。这块主要的出错点是自己设计的判断是否全面,可能出现不能全部AC的情况。
下面给大家整理的是我遇到的一些图论知识的题目,见过题目即可,再变形也变不到哪里去的。

哈密顿图

哈密顿圈 :经过图中所有的节点的圈 。

  • 是否是N+1个点。
  • 结点编号是否在范围内
  • 除起点外,每个点是否只出现了1次
  • 经过的边是否存在
  • 起点是否等于终点

练习题:PAT A 1122

欧拉图

首先用深度搜索(或者并查集)判断是否是联通图,如果不联通则不是欧拉图。然后统计每个节点的度数,就能判断。

  • Eulerian path:欧拉路径 (每条边经过一次)
  • Eulerian circuit:欧拉回路(起点终点是同一个点的欧拉路径)
  • 连通图中每个点的度数为偶数,则存在欧拉回路。这个图成为欧拉图。
  • 如果有两个点的度数为奇数,存在欧拉路径不存在欧拉回路。这个图称为半欧拉图。

练习题:PAT A 1126

maximal clique

(也是给的一个什么定义,其实都是大差不差的)
练习题:PAT A 1142

旅行商环路

练习题:PAT A 1150

并查集★★★

并查集不难,学会套路即可。最多会让你最后统计有几个并集、每个并集里有多少元素。

练习题:PAT A 1118PAT A 1107
忒麻烦的一题:PAT A 1114

拓扑排序★★★

拓扑排序跟并查集一样,可能会考,反正也不难,会一题就行。
练习题:PAT A 1146

最小生成树★★★

好像没考过,掌握Prim算法和Kruskal算法的基本使用即可。


树★★★★★

树这玩意,也是PAT每年必考啊,但是PAT的考风跟上机考试不一样,这里总结的PAT风格题目,其他同学可以拿来巩固数据结构。
考PAT的胖友每个点掌握一题,天下无敌。

树的遍历和性质★★★★

每种类型会一题即可,要理解中序后序前序的遍历方法和转化,到能推出公式的情况就天下无敌。除此之外,也会牵扯到递归迭代队列的使用。

已知先序中序求后序

变形练习:PAT A 1043

已知先序后序求中序

练习题:PAT A 1119

求结点数量

练习题:PAT A 1115PAT A 1127

知道树的结构求层次

练习题:PAT A 1123

已知中序后序求层次

PAT A 1127
变形:1064

已知前序中序求后序

练习题:PAT A 1138

已知层序求后序

练习题:PAT A 1147

判断是否是完全二叉树

练习题:PAT A 1110

中缀表达式

PAT基本不考,但是会了给你数据结构老师长点面子。考研复试的最好准备一下,考了写不出来有点蛋疼。这也是经常跟迭代和递归一起考的,建议多找几题来练习练习。
PAT A 1130

找共同祖先

这个最好会一下,虽然可能性不大。但是这是对数据结构最起码的尊重...
PAT A 1143PAT A 1151

建树★★

建树太复杂不咋考。考到也就是模板,会者就默,不会者弃。大家有空就看,没空放弃。看了反正估计也不考,考了没看也不亏....

建AVL树

练习题:PAT-A 1066PAT A 1123

建二叉搜索树

练习题:PAT A 1115


STL和数据结构★★★★★

STL在PAT中会刻意考察,一般在第二题。题目不难,题意复杂,浪费时间多,看题目太长可以最后做。在 考研上机 中,会掺和到各种题目里面,用和不用都能做,但是可能牵扯到空间时间解法简便性的问题。建议做题前首先考虑用这个数据结构合不合适,可不可以把题解决掉。否则用了再换重新写很浪费时间。
过程中涉及到字符串与数字的转化哈希存储等方法。
必须掌握的有:vector,set,map(unprdered_map),queue(priority_queue),stack。
嵌套的数据结构考的不是很多。

PAT专用题目★★★★

  • 题目非常长,输入非常多,从简单开始多练习。
  • 各种让你用数据结构存储排序查找输出。最难到STL的运算符重载,会一道题即可。

值得写的一道考点非常全面的一题:PAT A 1153
这道无敌无敌无敌大题目,会了天下无敌,包括我上面描述的所有考点,涉及多种数据结构,也涉及到了STL运算符的重载。也是我考试的题目,我懒得写一遍了,太长了,大家自己研究查查答案吧。这题是我耗时最多的题,题目看完都20分钟过去了。

练习题:PAT A 1129PAT A 1121PAT A 1124PAT A 1137PAT A 1141PAT A 1149

你若还不熟的其他练习题:PAT A 1012,PAT A 1016,PAT A 1022,PAT A 1025,PAT A 1028,PAT A 1039,PAT A 1047,PAT A 1054,PAT A 1055,PAT A 1062,PAT A 1063,PAT A 1071,PAT A 1075,PAT A 1080,PAT A 1083,PAT A 1100

数组、哈希和散列★★★

专门考到的可能性不大,但是总是透露在各个题目之中。当你想不到合适简便的存储方法的时候不妨考虑下哈希吧!除此之外,也看下哈希存储的几种避免冲突的方法,这个可能让你模拟先存后取算平均路径

哈希表:PAT A 1145
练习题:PAT A 1048、PAT A 1050、PAT A 1092、PAT A 1084

链表★★

链表你要是不会就有点说不过去了,把数据结构书上的掌握,考研涉及的题目用程序写出来,就差不多了。一般会考查找插入删除排序(原地反转)查找共同的节点等。想难得话也可以很难,那是故意考数学和逻辑的。总之基本的编程掌握,剩下的看脑子了。我这类题目没有专门看过,就网上挑了几个给大家看看。

练习题:PAT A 1032、PAT A 1052、PAT A 1074、PAT A 1097

队列和堆栈★★

队列和堆栈更偏向于应用,要是专门考的话,应该也一眼就能看出来。队列可以夹在BFS和层次遍历里面练习。题目我就不找了,应该不难。

PS:哈夫曼树一个简单解决方法就是priotity_queue(),哈夫曼树的相关题目可以准备一下


动态规划★★★

PAT中动态规划出现次数不是很多,即使考的话是基本模板题。考研上机中动态规划可能会作为压轴题出现,所以要多练习和体会。

最长不下降(上升)子序列★★★★★

这是经典题目,可能会出变形,你认出来真面目即可。

练习题:PAT A 1045
经典变形:1045

最大连续子序列★★★★★

经典。

练习题:PAT A 1007

判断回文★★★

经典的二维题目。

练习题:PAT A 1040

贪心算法★★★

练习题:PAT A 1125,PAT A 1033,PAT A 1037,PAT A 1038,PAT A 1067,PAT A 1070

0-1背包★★★

练习题:PAT A 1068

补充1:完全背包问题★★

// 完全背包问题
/* 
背包容量为m,物品的体积为w价值为v ,要求背包可以撞下价值尽可能多的物品,求最大价值,
背包可不被装满,每种物品数量**不限** 
每种物品两种情况:存在和不存在 
跟01背包的不同:顺序更新,因为每个物品可以多次选择 
*/ 
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
#define MAX 6
#define VEC 22 

int main(){
    int w[MAX] = {1,2,3,4,5,6};
    int v[MAX] = {3,4,2,5,1,3};
    int dp[VEC+1] = {0}; //初始值为0 
    
    for(int i = 0; i < MAX; i++ ){
        for(int j = w[i]; j <= VEC; j++){ //对于每一个总重,都要计算一下选不选物品i 
            dp[j] = max(dp[j-w[i]]+v[i], dp[j]); 
        }
    } 
    cout<<dp[VEC]; //答案为66 
    
    return 0;
}

补充2:多重背包★★

// 多重背包问题
/* 
与01背包的不同:每个物品有k件
解决方法,将k件物品进行拆分成,1,2,4,...件物品的和,组成新的物品
为啥这样拆分? 因为所有数字都可以用二进制表示,也就可以用a_1*2^0+a_2*2^1...表示
拆分后转化成01背包问题即可 
*/ 
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
#define MAX 6
#define VEC 22 

int main(){
    int w[MAX] = {1,2,3,4,5,6};
    int v[MAX] = {3,4,2,5,1,3};
    int k[MAX] = {1,2,7,31,12,14}; //每件物品的数量 
    int dp[VEC+1] = {0}; //初始值为0 
    
    /*新增代码片*/  
    vector<int> ww,vv; //新的体积和价值 
    for(int i=0;i<MAX;i++){
        int c = 1;
        while(k[i] - c > 0){
            k[i] -= c;
            ww.push_back(c*w[i]);
            vv.push_back(c*v[i]);
            c *= 2;
        }
    } 
    /*新增代码片*/
    
    for(int i = 0; i < ww.size(); i++ ){
        for(int j = VEC; j >= ww[i]; j--){ //对于每一个总重,都要计算一下选不选物品i 
            dp[j] = max(dp[j-ww[i]]+vv[i], dp[j]); 
        }
    } 
    cout<<dp[VEC]; //答案为29 
    
    return 0;
}

补充3:最长公共子序列★★★★★

//最长公共子序列
#include<iostream>
#include<vector>
#define MAX1 9 
#define MAX2 7 
using namespace std;

int main(){
    int a[MAX1+1] = {0,0,1,2,3,4,5,6,7,8};
    int b[MAX2+1] = {0,9,1,2,6,3,4,5} ;
    int dp[MAX1+1][MAX2+1];
    for(int i = 0; i <= MAX1; i++){
        dp[i][0] = 0; 
    } 
    for(int j = 0; j <= MAX2; j++){
        dp[0][j] = 0; 
    } 
    for(int i = 1; i <= MAX1; i++){
        for(int j = 1; j <= MAX2; j++){
            if(a[i] == b[j]){
                dp[i][j] = dp[i-1][j-1] + 1;
            }else{
                dp[i][j] = max(dp[i-1][j], dp[i][j-1]);
            }
        }
    }
    cout<<dp[MAX1][MAX2];
    return 0;
} 

排序和基本搜索★★★

会数据结构书上的:二分搜索、快速排序、冒泡排序等。基本算法,这里不再提。
考研上机必须作为基础题目。PAT的话感觉没咋考过.....考的话应该也不难...总之想到了就不难...

堆排序★★★

这个模块特地提一下堆排序,是重要且容易考的。
堆的话,掌握两个点即可:堆的建立、排序
给大家一段参考代码,会了基本没什么问题。

/*
第一步:构建最小(大)堆  
第二步: 向下(上)调整   O(log_2 n)
*/
#include<iostream>
#include<vector>
using namespace std;
#define MAX 9

int a[MAX+1] = {0,5,3,1,7,4,2,0,6,8}; //后9个数排序 

void swap(int x, int y){
    int t = a[x];
    a[x] = a[y];
    a[y] = t;
}
 
void adjustDown(int r, int n){
    int child = 2*r;
    int val = a[r];
    while(child <= n){
        if(child < n && a[child] > a[child+1]) child++;//选取孩子较小的那个
        if(val < a[child]) break; //若父节点最小,则不需要调整
        a[child/2] = a[child];
        child *= 2; //到下一层 
    }
    a[child/2] = val;
}

int main(){
    
    /*建最小堆*/ 
    for(int i = MAX/2; i > 0; i--){//从第一个非叶子节点开始 
        adjustDown(i, MAX); 
    } 
    cout<<"建堆:"; 
    for(int i=1;i<=MAX;i++){
        cout<<a[i]<<" ";
    }
    cout<<endl;
    
    /*排序*/
    for(int i = MAX; i > 1; i--){
        swap(1,i);
        adjustDown(1,i-1); 
    } 
    cout<<"排序:"; 
    for(int i = MAX;i > 0; i--){
        cout<<a[i]<<" ";
    }
    cout<<endl;
    
    return 0;
}  

练习题: PAT A 1147,PAT A 1098


数学、逻辑、模拟、字符串、递归等★★★

这个为啥放在一起讲呢,明明别的书都是分开讲的。因为剩下的都是基础,没有模板可套,考验脑子分析问题和建模能力。给你再多例题也白搭,到时候换个新的会做的人还是会做,不会做的人还是不会做。不过不用太紧张,这种题目一般放在第一题,作为简单题考查。编程能力够了之后就不用训练太多,但是了解一些经典题目和算法还是有必要的。给大家整理一些我碰到的。

素数判断★

素数判断有几种方法,请都掌握。

练习题:PAT A 1116

推公式的★

练习题:PAT A 1104

数位和★

其实也可以看成字符串处理问题...

练习题:PAT A 1120

逻辑题★★

螺旋矩阵问题:PAT A 1117PAT A 1113PAT A 1109
8皇后问题:PAT A 1128
回文:PAT A 1136PAT A 1140PAT A 1144

模拟★★★

这个模拟啥的都有可能,其实就编程能力的问题。

练习题:PAT A 1105

字符串处理★★★★

一般专门考察会涉及到一个字符一个字符的处理的细节性问题,混在别的题目考的话是考输入、输出、转化等整体性的问题。
自己看一下C++ string的用法,这个渗透于各个题目中。
练习题:PAT A 1112PAT A 1108PAT A 1140

递归★★★

单独考的话会跟数学一起考,考察建模、分析问题能力。经常和图什么的混在一起考。
练习题:PAT A 1130PAT A 1131

尺取法★★

这个是自己想到的一种方法,后来发现有个学名叫“尺取法”.......

练习题:PAT A 1044

枚举★

没办法就暴力呗...

练习题:PAT A 1148


其他★

目前只想到下面几个....

大数

都是很简单,其实可以看作是字符串处理。加减会做,乘除不用会;

练习题:PAT A 1023,PAT A 1024

找出下一个排列★

嗯...可以当作逻辑题自己推倒的,也不难,但是C++有封装好的方法给大家提示一下...我自从知道了之后就再也不自己推倒了....

//最后一个排列没有下一个排列,用next_permutation会返回false
#include<iostream>
#include<vector>
#include <algorithm> 
#define MAX 7
using namespace std;

int a[MAX] = {2,1,4,7,6,3,5};
vector<int> v(a, a+MAX);

void shuchu(){
    for(int i=0;i<v.size();i++){
        cout<<v[i]<<" ";
    }
    cout<<endl;
}

int main(){
    shuchu();
    next_permutation(v.begin(), v.end());
    shuchu();
    prev_permutation(v.begin(), v.end());
    shuchu();
    return 0;
} 

附录A:数据结构范围

了解之后才能更知道题目想考察你什么。

数据类型 用10表示 用2表示
unsigned int 0, 4×10^{9} 0, 2^{32}-1
int -2×10^{9}, 2×10^{9} -2^{31}, 2^{31}-1
unsigned long 0, 4×10^{9} 0, 2^{32}-1
long -2×10^{10}, 2×10^{10} -2^{31}, 2^{31}-1
long long 0, 9×10^{18} -2^{63}, 2^{63}-1
unsigned long long 0, 10^{19} 0, 2^{64}-1

顺便复习一下精度

数据类型 比特位数 有效数字 用10表示 用2表示
float 32 6~7 -3.4*10^{38}~+3.4*10^{38} -2^{128} ~ +2^{128}
double 64 15~16 -1.7*10^{-308}~1.7*10^{308} ——
long double 128 18~19 -1.2*10^{-4932}~1.2*10^{4932} ——

附录B:输入、输出、初始化

这里不谈一般方法,重点说几种会了救命的方法。我就想起了一点儿,剩下的自己总结....

输入输出

1. C++保持4位数,不满4位前面用0表示

cout<<setw(4)<<setfill('0')<<x<<endl;

2. C保持4位数,不满4位前面用0表示

printf("%04d",x); 

3. sscanf, sprintf 两个自己查一查

初始化矩阵

1. fill的用法(可赋任何值)

#初始化一维矩阵
int dis[505];
fill(dis, dis+505, ); #赋值为无穷大

#初始化二维矩阵
int cost[505][505];
fill(cost[0],cost[0]+505*505,-1);  #赋值为-1

2. memset的用法(只能赋值0和1)

#include<string> #注意头函数

char str[10];
memset(str,  0,  sizeof(str));

附录C:机试常用STL方法总结

vector,set和map

vector set map
初始化 vector<int> v1 = {1,2,3};
vector<int> v2(5); #默认初始化为5个0
vector<int> v3(5, -1) #初始化为5个-1
一般不考 一般不考
添加元素 v.push_back(元素); s.push() m.insert(pair<int, string>(5, "hh"))
弹出元素 v.pop_back(); s.pop() 一般不考
判断是否为空 v.empty() s.empyt() m.empty()
计算元素个数 v.size(); s.size() m.size()
删除所有元素 v.clear(); s.clear()
s.erase(某个元素)
m.clear()
m.erase(迭代器)
查找某个元素 跟数组差不多 s.find(元素) m.find(元素)
遍历 跟数组差不多 迭代器 迭代器
其他 二维:vector< vector<int> > 可重复set: muliset<int> 不排序map:unordered_map<int , string>

stack和queue

stack queue
添加元素 s.push(元素) q.push(元素)
弹出元素 s.pop() q.pop()
访问元素 s.top() q.front()
q.back()
判断是否为空 s.empty() q.empty()
计算元素个数 s.size() q.size()
补充 大根堆priority_queue<int>
小根堆:priority_queue<int, vector<int>, greater<int> >

附录D:过程中出现的问题总结

就想起来三个...大家自己总结吧!

1. 全局变量在静态存储区分配内存,局部变量是在栈上分配内存空间。如果数组太大,可能会造成栈溢出 :因此可将大数组那到main函数外。
2. 数组比题目给出范围大5~10.
3.用int会把0和00000混淆,所以还是用string若用int在做题时方便且不冲突,则可用填充0的方式输出即可。


附录E:PAT A 审题小锦囊

题目不需要都看

用我考试的PAT A 1152 题为例,题目如下:






题目一般分为3个部分:背景、输入、输出。
你做多了发现其实背景经常没啥用,其实直接从输入看就可以了。
所以我考试的时候直接忽略前面(别看还给你注明了一个“超越数”唬人),从输入看的。最后做的很快啊。也AC了。至今我都没看这题到底跟Google和超越数有啥联系...

常用英文词汇

我一开始做题经常查.....看多了发现就那几个词....

英语单词 翻译
permutation 排列、置换
real numbers 实数
accurate up to 精确到
2 decimal places 两位小数
be rounded to 四舍五入
syntax 语法
parentheses 圆括号
precedences 优先
Palindrome 回文
standard notation 标准符号
iteration 迭代
incompatible 不相容的
combinatorial 组合的
operations research 运筹学
distinct 不同的
prime 素数
topological order 拓扑序

附录F:常用包和模板

去了考查先写下来,然后复制粘贴,比较节省时间。

常用包

emmmm...不要以为你用C++了以后,stdio.h和string.h包就不用了,其实在做这种题目的时候,有时候还是还是C方便,加入反正也不麻烦。

#include<stdio.h>
#include<stdlib.h>
#include<cmath>
#include<string>
#include<string.h>
#include<set>
#include<map>
#include<queue>
#include<stack>

模板

模板先写好,回头复制粘贴一条龙。vector每题基本都要用,没有说特别针对只能用数组不能用vector的题目。

#include<iostream>
#include<vector>
using namespace std;
int main(){
    
    return 0;
} 

附录G:评分细则

官网给你们扒下了,其实我做题目都用的很少...



最后祝大家取得好成绩!
点赞哦~

推荐阅读更多精彩内容