【PAT】练习总结

PAT 练习总结

笔记

  1. 设置存储hash的数组可以尽量设大一点。

  2. 查找一串数字里是否存在某个数的问题一般用hash

  3. c++中map可随意访问、任意插入,index,vector不行。

  4. ASCII码共有128个,其中比较常见的ASCII码:

    1. 10 = ’\n‘
    2. 48~57: 0 ~ 9
    3. 65 ~ 90: ’A‘ ~ ’Z‘
    4. 97 ~ 122: ‘a’ ~ ‘z’
  5. C语言定义数组的方法:

    1. int a[] = {1, 2, 3}; // 不定长数组,长度由元素个数决定。
    2. int a[N];// 定长数组 。
    3. int *a;// 定义指针
  6. 二维数组:

    1. int a[10][10]
    2. vector<int> a[10]
    3. char a[10][10]:字符串数组
  7. C语言往函数传数组的方法:

    1. int fuc(int *a, int size){int n = *(a + 0)}; // 传入指针和大小两个变量
    2. int fuc(int a[], int size){}; // 传入数组和大小两个变量
    3. int fuc(int a[10]){}; // 只传入数组一个变量
  8. 判断某数是否为素数:

    bool isPrime(int n){
        if(n == 0 || n == 1)	return false;	// 要考虑数字0和1
        for(int i = 2; i <= sqrt(n); i++)	// 是i <= sqrt(n),而不是 i <= n / 2。
            if(n % i == 0)	return false;
        return true;
    }
    
  9. 使用sqrt()需要#include <cmath>

  10. 正向平方探测法,pos = (key + i * i)% Tsize (0 <= i < Tsize)

  11. C++中tolower()函数是把字符串都转化为小写字母,touppre()函数是把字符串都转化为大写字母。

    • 需要#include<iostream>#include<cctype>
  12. isupper()isdigit()等判断字符的函数在头文件cctype

    • 特别的,stoi()是c11特性,不需导入头文件
  13. isdigit()不需要调用什么包;

  14. 将字符串 string 转化为对应的 int 型、 double 型变量stoistod

  15. stoi():只能将string型变量变成int类型变量(字符、字符数组不行!)

  16. 把int / float变成字符串to_string(int/float)

  17. getline(cin, str),这个函数可读入一整行的字符串(包括空格

  18. 在字符串中查找字符可用str.find(c),若没找到,会返回string::npos。所以判断字符串中有无字符可用if(s.find(c) != string::npos)

  19. 查找字符串a是否包含子串b,不是用strA.find(strB) > 0strA.find(strB) != string:npos

  20. 获取字符串的子串str.substr(index) / str.substr(index, num)

    • str.substr()分割字符串;
  21. for循环内判断和赋值的灵活使用

    可以用for循环找到不符合条件的元素的下标j,如:

    for(j = i; j < s.length() && s[j] == s[i]; j++); // 找到与当前数字s[i]不同的数字的下标 or 记录最后一个数字后一位下标
    
  22. C语言的scanfprintf语法:

    1. 输入字符串:

      #include <iostream>
      int main(){
          char a[100];
          scanf("%s", a);	// input
          printf("%s", a);	// output
          return 0;
      }
      
    2. 字符串的方法(如strlen() )时要#include <string.h>#include <string>没用)

    3. c语言字符串用strlen()要调用#include <string.h>

    4. #include <iostream>
      
      int main(){
          double a;
          scanf("%lf", &a);	// 若输入2.3.4,赋值给a的值是2.3
          return 0;
      }
      
    5. double型变量:

      • scanf格式符为%lf
      • printf格式符为%f
    6. 输出格式:

      1. %md:使不足m位的的int型变量以m位进行右对齐输出,高位用空格补齐
      2. %0md:同上,不同处是用0补齐
      3. %.mf:使浮点数保留m位小数输出
  23. C++的sscanfsprintf语法:

    1. 两者均在#include<cstdio>头文件下

    2. 返回值:

      1. sscanf():如果成功,该函数返回成功匹配和赋值的个数。如果到达文件末尾或发生读错误,则返回 EOF。

        即,若输入不规范,不会把不规范的东西赋值给变量

      2. sprintf():如果成功,则返回写入的字符总数,不包括字符串追加在字符串末尾的空字符。如果失败,则返回一个负数。

      3. sscanf()可以理解为:string+scanf;

        ssprintf()可以理解为:string+printf;

        理解:

        1. scanf("%d",&n);printf("%d",n);可以理解为:(screen表示屏幕)
          1. scanf(screen,"%d",&n);:把screen的内容以"%d"的格式传输到n中 (从左到右)
          2. printf(screen,"%d",n);:把n以"%d"的格式传输到screen上 (从右到左)
        2. sscanf()sprintf()
          • sscanf(str, "%d", &n);:把string的内容以"%d"的格式传输到n中 (从左到右)
          • sprintf(str, "%d", n);把n以"%d"的格式传输到string上 (从右到左)

        转自这篇博客

      4. sscanf()sprintf()比较复杂的应用:

        1. sscanf():

          #include <cstdio>
          using namespace std;
          int main()
          {
          	int n;
          	double db;
          	char str[] = "2018:3.14,hello";
          	char s[100];
          	sscanf(str, "%d:%lf,%s", &n, &db, s);
          	printf("n=%d  db=%.2f  s=%s", n, db, s);
          	return 0;
          }
          

          输出:

          n=2018  db=3.14  s=hello
          
        2. sprintf():

          #include<cstdio>
          using namespace std;
          int main()
          {
          	int n=12;
          	double db=3.1415;
          	char s[] = "good";
          	char str[100];
          	sprintf(str, "%d:%lf,%s", n, db, s);
          	printf("%s\n",str);
          	return 0;
          }
          
          

          输出:

          12:3.141500,good
          
  24. 只有C++有getline(cin, str),C语言没有

  25. cin >> n;后如果要用getline(cin, str),需要先cin.ignore();

    因为输入n后会有一个\n,会导致getline()捕获这个\n后中断,所以要加cin.ignore();

  26. reverse(a.begin(), a.end):逆序(或反转),多用于字符串、数组、容器,只能转置线性容器

    • #include <algorithm>

    • 用于反转在[first,last)范围内的顺序(包括first指向的元素,不包括last指向的元素),reverse函数无返回值。

    • sort()一样,只能对线性容器进行排序(如vectorlistdeque)。map和set都是按键值对存的,所以不能用

  27. a为浮点数时,to_string(a)只会保留小数点后6位小数

  28. 结构体增加一个元素:{it.first, it.second}

  29. STL容器:

    1. string

    2. vector

      1. 初始化:vector<int> v;

        • 初始化时定义大小后会初始化为0,不定义大小就不会初始化为0;

          vector<int> v(10);	// 初始化vactor大小为10,其中每个元素都被初始化为0
          vector<int> v	// 大小和元素都没被初始化
          
        • 若想输入vector的值,需要先初始化为0

      2. 在v的最后插入一个新元素:v.push_back(i)

    3. map

      • 初始化:map<string, int> m;
        • 初始化后所有元素被初始化为0
      • 因为map按键值排序了,所以不能按顺序输出munordered_map则是无序存储的,也不能按顺序输出m
    4. set

      • set自动排序去重

      • set,unordered_set:set是有序的(从小到大排序);unordered_set是无序的,数据的存放位置也是是无序的

      • 访问元素:用迭代器

      • 查找特殊元素:

        #include <iostream>
        #include <set>
        using namespace std;
        
        int main(){
            set<int> s = {0, 3, 1, -2, 10};
            auto pos = s.find(-2);   // 先找这个元素的位置,返回一个迭代器
            cout << *pos;   // 取值,输出
            return 0;
        }
        
    5. 遍历容器的方法

      1. 使用迭代器遍历v.begin()是⼀个指针,指向容器的第⼀个元素, v.end() 指向容器的最后⼀个元素的后⼀个位置,所以迭代器指针it 的for循环判断条件是it != v.end()

        vector<int> v = {1, 2, 3};
        for(auto it = v.begin(); it != v.end(); it++)	// auto相当于 vector<int>::iterator 的简写
                cout << *it << endl;	// 访问vector的元素用*it
        
        map<int, int> m;
        m[1] = 100;
        m[2] = 200;
        for(auto it = m.begin(); it != m.end(); it++)
            cout << it -> first << " " << it -> second << endl;	// 访问map的键用it -> first,访问map的值用it -> second
        
        • auto 是C++11⾥⾯的新特性,可以让编译器根据初始值类型直接推断变量的类型
      2. 基于范围(range-based)的for循环:遍历数组中的每个元素

        int a[3] = {1, 2, 3};
        for(int i : a)
            cout << i << endl;
        
        vector<int> v = {1, 2, 3};
        for(auto it : v)
            cout << it << endl;
        
  30. sort()、自定义cmp

    • #include <algorithm>
    • 注意传入cmp的变量都是地址
    • 升序:a > b;降序:a < b
    • sort算法只能对线性容器进行排序(如vectorlistdeque),map是一个集合容器,它里面存储的元素是pair,不是线性存储的(像红黑树),所以利用sort不能直接和map结合进行排序;
  31. 若运行超时,可能是用了cout,改成printf()一般就能解决问题。

  32. 避免超时的方法:

    1. 空间换时间
      1. hash
      2. 能map直接找到对应的值,就别用for循环一个一个找
    2. 不用cin、cout,用scanf()、printf()
    3. 在循环里,可用提前用break;return 0退出;
    4. for循环外面定义i
    5. 如果使用mapset超时了,不考虑排序的情况,可以用unordered_mapunordered_set
  33. 结构体:定义结构体数组时,vector<>里是结构体名称,不是变量名;

    struct good_pair{
        string good1;
        string good2;
    };
    
    vector<good_pair> list(n);
    
  34. 初始化数组元素的方法:

    1. 定义成全局变量,即将int a[N]放在main外,这样a所有元素都会被初始化为0;

    2. int a[10] = {0};
      
    3. vector的初始化:

      vector<int> a(10);
      
  35. vector<item> query(n); 结构体也会被初始化为0;

  36. map[key]查询无果,就会返回0

  37. 重载和引用(详细笔记看这):

    • 重载(来自菜鸟教程):名字相同,参数和定义不同。

    • 引用:和原变量本质上是一个东西,只不过是原变量的一个别名

  38. 在vector里查找是否有某元素:若query.find(q) == query.end()true,说明没找到;为false,说明找到了。

  39. 要排序的东西可以放到数组里

  40. 排序有很多要求时,结构体真的很好用

  41. 以后多用三目运算符,可以减少代码量。

  42. 如果一个东西有多个属性,就用结构体

  43. 结构体的元素可以用{}表示;

    struct stu{
        string name;
        int age;
        int sex;
    };
    int main(){
        stu student1 = {"Lily", 10, 1};
    	stu student2 = stu{"Tom", 11, 0};	// 也可在打括号前写结构体名字
        return 0;
    }
    
  44. 四舍五入:round()

    1. #include <cmath>
    2. round(x)返回x的四舍五入整数值。
    3. ceil(x)返回不小于x的最小整数值(然后转换为double型)。
    4. floor(x)返回不大于x的最大整数值。
  45. 若思路很乱,可尽可能用多的容器/遍历去存多个信息。比如有一题里学校的信息就可以用三个容器:

    1. vector<applicant> sch[101];:存学校里面的学生信息

    2. int quota[101] = {0};:存学校的招生指标

    3. int cnt[101] = {0};:存学校当前录取的学生数

      这样思路清晰、操作方便;

  46. 可以将完成某项工作的代码封装成函数,如“判断素数”、“数字转换”和“计算和”之类的;

  47. 用太多stl容器容易超时

  48. 如何获得一个整数的各位数:

    int num;
    scanf("%d", &num);
    while(num != 0){
        printf("%d ", num % 10);
        num /= 10;
    }
    
  49. v.resize(k)给v重新定义大小后,可以直接输入

    stu[i].choices.resize(k);
    for(j = 0; j < k; j++)
        scanf("%d", &stu[i].choices[j]);
    }
    

易错

  1. string类型的变量只能用cin输入,不能用scanf()输入!!!

    输出可用coutprintf(),但是要先把变量.c_str()printf("%s", str.c_str())

    • 为了与C兼容,在C中没有string类型,故用printf()输出string时,必须通过string类对象的成员函数c_str()把string对象转换成C中的字符串样式
  2. 查找字符串a是否包含子串b,而strA.find(strB) != string:npos;判断字符串中有无字符可用if(s.find(c) != string::npos)

  3. 有关数字的问题,要注意num == 0的情况

  4. 我做题经常有一两个测试点每通过,是因为一般情况下我只考虑所给样例里的情况,没有严谨的所有情况。我做题都是凭直觉,一点都不严谨!!!要注意细节。

  5. for有循环内多个判断条件:注意i++或者i--

  6. 输出时要注意英文的单复数形式!!!

    • n = 1时输出:“There is 1 account.”
    • n > 1时输出:“There are 3 accounts.”
  7. if()里有多个判断条件记得要打括号

  8. 数组不能设得太大了,不然会报栈错误

  9. 如果数字太大,是不能用普通的hash去存的,因为没有那么大的数组,用map存就能解决问题。

  10. i定义在for循环外后,再用的时候忘记初始化了,所以一直报栈溢出的错;

  11. while()里的判断条件应该if()一样的,符合条件才执行循环语句里的东西

  12. 注意while()允许运行的条件是满足条件的时候,还要注意i == 0的情况!

  13. 别把要输入的变量定义成测试样例里的值!

  14. 若删除set元素后还需迭代set,记得要更新迭代器的位置,因为set已经变了,如:

     while(it != singles.end()){
            if(singles.find(couples[*it]) != singles.end()){ // 有一对情侣就将他们删除
                singles.erase(*(singles.find(couples[*it])));   // 先删除这个人的情侣,再删除这个人
                singles.erase(*it);
                it = singles.begin();   // 因为删除后set变了,该从头遍历set
            }
    
  15. while(one[j] != one_part) j++;去找元素可能会出现数组越界,会报段错误,改成用for去找,就能解决段错误了。

  16. 访问数组元素时,经常用错下标,比如:

    for(i = 0; i < 10; i++){
        for(j = 0; j < 5; j++){
            if(s[j] == '0')		// 我经常会粗心写成s[i]
                printf("%c\n", s[j]);
        }
    }
    
  17. 有时候偷懒,想复制之前写好的部分,会忘记改了,比如:

    if(m < 12 && ten[m] == one_part){   // 从下面复制ten[m] == ten_part忘记改成ten[m] == one_part
    
  18. (int / int) 为int类型,若想获得float类型,应先将int变量强制转换成float类型

  19. 若我想生成二维vector,在往二维vector里插入新vector时,要注意新vector的类型要和二维vector定义的一致

题目分类

类型题目刷题笔记
hash1154
hash1145
hash1134
hash1092 To Buy or Not to Buy (20 分)https://blog.csdn.net/SSibyl/article/details/115559781?spm=1001.2014.3001.5501
hash1084 Broken Keyboard (20 分)https://blog.csdn.net/SSibyl/article/details/115920266?spm=1001.2014.3001.5501
hash1078 Hashing (25 分)https://blog.csdn.net/SSibyl/article/details/116198964?spm=1001.2014.3001.5501
hash1050 String Subtraction (20 分)https://blog.csdn.net/SSibyl/article/details/116199564?spm=1001.2014.3001.5501
hash1048 Find Coins (25 分)https://blog.csdn.net/SSibyl/article/details/116210005?spm=1001.2014.3001.5501
hash1041 Be Unique (20 分)https://blog.csdn.net/SSibyl/article/details/116210571?spm=1001.2014.3001.5501
字符串1152 Google Recruitment (20 分)https://blog.csdn.net/SSibyl/article/details/116242675?spm=1001.2014.3001.5501
字符串1140 Look-and-say Sequence (20 分)https://blog.csdn.net/SSibyl/article/details/116243889?spm=1001.2014.3001.5501
字符串1108 Finding Average (20 分)https://blog.csdn.net/SSibyl/article/details/116352827?spm=1001.2014.3001.5501
字符串1082 Read Number in Chinese (25 分)https://blog.csdn.net/SSibyl/article/details/116357128?spm=1001.2014.3001.5501
字符串1077 Kuchiguse (20 分)https://blog.csdn.net/SSibyl/article/details/116358127?spm=1001.2014.3001.5501
字符串1073 Scientific Notation (20 分)https://blog.csdn.net/SSibyl/article/details/116428996?spm=1001.2014.3001.5501
字符串1061 Dating (20 分)https://blog.csdn.net/SSibyl/article/details/116536169?spm=1001.2014.3001.5501
字符串1035 Password (20 分)https://blog.csdn.net/SSibyl/article/details/116463362?spm=1001.2014.3001.5501
字符串5. 1005
字符串6. 1001
STL1153 Decode Registration Card of PAT (25分)https://blog.csdn.net/SSibyl/article/details/116497987?spm=1001.2014.3001.5501
STL1149 Dangerous Goods Packaging (25 分)https://blog.csdn.net/SSibyl/article/details/116543547?spm=1001.2014.3001.5501
STL1144 The Missing Number (20 分)https://blog.csdn.net/SSibyl/article/details/116545641?spm=1001.2014.3001.5501
STL4. 1141
STL1137. Final Grading (25)https://blog.csdn.net/SSibyl/article/details/116712638?spm=1001.2014.3001.5501
STL1129 Recommendation System (25 分)https://blog.csdn.net/SSibyl/article/details/116712459?spm=1001.2014.3001.5501
STL1124 Raffle for Weibo Followers (20 分)https://blog.csdn.net/SSibyl/article/details/116716031?spm=1001.2014.3001.5501
STL1120 Friend Numbers (20 分)https://blog.csdn.net/SSibyl/article/details/117200788?spm=1001.2014.3001.5501
STL1121 Damn Single (25 分)https://blog.csdn.net/SSibyl/article/details/116719546?spm=1001.2014.3001.5501
STL1112 Stucked Keyboard (20 分)https://blog.csdn.net/SSibyl/article/details/116800307?spm=1001.2014.3001.5501
STL1100 Mars Numbers (20 分)https://blog.csdn.net/SSibyl/article/details/116806960?spm=1001.2014.3001.5501
STL1. 1095(没做)
STL1071 Speech Patterns (25 分)https://blog.csdn.net/SSibyl/article/details/116895581?spm=1001.2014.3001.5501
STL1063 Set Similarity (25 分)https://blog.csdn.net/SSibyl/article/details/116897670?spm=1001.2014.3001.5501
STL1054 The Dominant Color (20 分)https://blog.csdn.net/SSibyl/article/details/116900037?spm=1001.2014.3001.5501
STL1047 Student List for Course (25 分)https://blog.csdn.net/SSibyl/article/details/117092103?spm=1001.2014.3001.5501
STL1039 Course List for Student (25 分)https://blog.csdn.net/SSibyl/article/details/117201164?spm=1001.2014.3001.5501
排序1. 1153
排序2. 1141
排序3. 1137
排序1125 Chain the Ropes (25 分)https://blog.csdn.net/SSibyl/article/details/117201592?spm=1001.2014.3001.5501
排序1113 Integer Set Partition (25 分)https://blog.csdn.net/SSibyl/article/details/117248636?spm=1001.2014.3001.5501
排序1101 Quick Sort (25 分)https://blog.csdn.net/SSibyl/article/details/117255502?spm=1001.2014.3001.5501
排序1083 List Grades (25 分)https://blog.csdn.net/SSibyl/article/details/117253941?spm=1001.2014.3001.5501
排序1080 Graduate Admission (30 分)https://blog.csdn.net/SSibyl/article/details/117373576?spm=1001.2014.3001.5501
排序1062 Talent and Virtue (25 分)https://blog.csdn.net/SSibyl/article/details/117464964?spm=1001.2014.3001.5501
模拟1002 A+B for Polynomials (25 分)https://blog.csdn.net/SSibyl/article/details/118694245?spm=1001.2014.3001.5501
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值