算法笔记1——基础篇(C++)

知识点

输入输出

  • gets() puts()
    PAT中不能使用puts()、gets(),可以用以下代码替换

    char a[100];
    fgets(a, 100, stdin);  //遇回车后停止输入,输入的最后一个字符为'\r'
    fputs(a, stdout); 
  • cin与cout

    #include<iostream>
    #include<iomanip>//在控制精度时
    using namespace std;
    int main(){
    	int n; double db; char c; char str[10];	
    	cin>>n>>db>>c>>str;
    	cin.getline(str,10);//整行读入
    	string str;
    	getline(cin,str);
    	cout<<n<<"  "<<db<<endl;//endl表示end line
    	//精度输出
    	cout<<setiosflags(ios::fixed)<<setprecision(2)<<123.456<<endl;
    }
  • scanf()与gets输入字符串
    使用scanf("%s",str);读取字符串时,以空白符(空格、Tab)和换行为截至标志,如果有空格,只能读取空格前的一段字符串。
    scanf使用%c会将空格和回车读入,可以使用getchar()在之前吸收空格。
    使用fgets(str,maxn,stdin)读取字符串时,以换行符作为截至标志,最后一个为’\r’.在使用scanf读取数据后,使用gets,需要在scanf之后加上getchar()吸收回车。
    cin读入字符串是以空格和换行结束的,读入一行使用getline(cin,str);

  • 用户给定长度的数组

    //错误范例
    int n;
    scanf("%d",&n);
    int a[n];
    //
    //正确范例
    const int N=100000;
    int main(){
    	int n;
    	int a[N];
    	scanf("%d",&n);
    }
  • 输入到文件末尾
    EOF表示-1,while(scanf("%d",&a) != EOF ){ } 直到文件末尾

  • char[]进行修改
    注意当修改后的长度小于之前的长时,应当最后一位置‘\0’

数据类型

  • 赋初值
    bool bool right[130]={true};是不行的,需要使用fill函数: fill(right,right+130,true);

  • char型变量大小写互换
    小写转化为大写c-=32;c=c-('a'-'A');
    大写转化为小写c+=32;c=c+'a'-'A';

  • long long与int
    当题目给出范围[-231 ,231]时(int的数据范围是[-231,231-1]),需要使long long类型,输入输出使用"%lld"。(数据范围[0,1010]同理)

  • long long数据计算溢出
    long long的范围[-263,263-1],两个两个整数相加会溢出。
    1.正溢出:A+B的最大值为264-2,long long存储正溢出之后的区间在[-263,-2](由(264-2)%264=2可得右边界)。当A>0,B>0,A+B<0为正溢出。
    2.负溢出:A+B的小大值为-264,long long存储负溢出之后的区间在[0,263-1](由264%264=0可得左边界)。当A<0,B<0,A+B>=0为负溢出。
    3.A+B不能直接在if中,必须先存储在long long类型变量

  • 浮点数的比较

    const double eps = 1e-8;
    #define Epu(a,b) ((fabs((a)-(b)))<(eps))  //(==)
    #define More(a,b) (((a)-(b))>(eps))  //(>)
    #define Less(a,b) (((a)-(b))<(-eps))  //(<)
    #define MoreEqu(a,b) (((a)-(b))>(-eps))  //(>=)
    #define LessEpu(a,b) (((a)-(b))<(eps))  //(<=)

文件读取

#include <fstream>
#include <iostream>
using namespace std;
int main ()
{
   char data[100];
   ofstream outfile;//输出文件流,创建文件,并向文件读取信息
   outfile.open("data.txt");// 以写模式打开文件
   cin.getline(data, 100);
   outfile << data << endl;// 向文件写入用户输入的数据
   cin.ignore(); 
   outfile.close();// 关闭打开的文件
 
   
   ifstream infile; //输入文件流,从文件读取信息
   infile.open("data.txt"); // 以读模式打开文件
   infile >> data; 
   // 在屏幕上写入数据
   cout << data << endl;
   infile.close();// 关闭打开的文件
   return 0;
}

日期计算

while(a.dd<b.dd||a.hh<b.hh||a.mm<b.mm){
  a.mm++;
  if(a.mm==60){
   a.hh++;a.mm=0;
  }
  if(a.hh==24){
   a.dd++;a.hh=0;
  }
 }

注意

  • 在for循环时,把循环条件写为i<strlen(str)不是好习惯,strlen函数本身内部实现是要时间。
  • 使用hash数组方法时,注意数组有界。

刷题记录

  • B1008.数组元素循环右移问题
    题目没有给定M的最大值,不能认为M<N,因此读入M、N之后需要 M=M%N
  • B1018.锤子剪刀布
    手势循环相克,k1剩k2表示为(k1+1)%3==k2
    手势的表示一维数组char mp[3]={'B'.'C','J'};
  • A1046.最短距离(超时)
    由于题设规定时间为100ms,数组最长105,查询最多104,若每次查询要遍历整个数组,需要109次操作。可以使用dis数组和sum累加,dis[i]表示从点(i-1)到点(1)的距离,dis(left,right)就是dis[right-1]-dis[left-1],时间复杂度O(1)。
  • A1065.A+BandC
    注意大数计算的溢出问题,以及A+B不能直接在if中,必须先存储在long long类型变量
  • B1010.多项式求导
    注意如何表示输入结束,关注一下《上机指南》中P24的方法和count的作用a[i-1]=a[i]*i; a[i]=0;//求导后当前系数必须清零,否则后面无法覆盖
  • B1041.考试座位号
    题目中机试座位号唯一,可以表示为数组下标,这样查找时可直接获取。
  • A1031 U型输出
    题目中看懂n1=n3=max{k|k<=n2 for all 3<=n2<=N} n1+n2+n3-2=N的意思,同时学会使用二维数组输出图形
  • B1037 零钱计算
    由于涉及到负数,可以直接将所有G.S.K转换为K进行计算之后再转化回来
  • A1077 求公共后缀
    由于输入的字符串中会有空格,因此不能用scanf,应使用fgets(最后一个字符是’\r’,应该str[i][slen-1]='\0';处理掉)。同时,在scanf与fgets之间使用getchar吸收换行符 。
  • B1029 旧键盘
    每个问题按键只输出一次,需要使用bool型数字HashTable[128]表示是否已经输出。(同时会字母大小写之间的转化)
  • A1048Find Coins
    注意HashTable[]的越界问题。money[i]<data&&?????????
  • A1067 Sort with Swap(0,*)
    在index[0]==0时寻找一个不在本位的数,从头枚举出现超时,应该定义一个k,记录不在本位的最小下标,每次枚举从k处开始。同时,明白index的意义,不再重复使用data[]
  • A1029 求两个数列中位数
    使用two pointers方法是可以在每一个数列末尾添加INF=(1<<31)-1,在扫描时,防止数组越界。
  • A1078 hashing
    题目要求二次方探测的方式处理冲突,公式为M=(a + step*step)%TSize当step从0~TSize-1枚举中没有找到位置,则表示插入失败(循环节为TSize)。当TSize不是素数时,重新赋值一个大于TSize的最小素数。
  • A1096 被连续数乘积整除
    注意当len为0时,输出的len为1,因子为n自身。在找到连续第一个数时,进入循环判断len,此时i的值不应该变化。
  • A1059 质因子
    注意n为1或素数时的特殊情况

注意思路

  • A1042 扑克牌(扑克牌的数组表示,next表示下一次的位置,end和start表示编号end[next[i]]=start[i];

  • B1048 数字加密(部分出错)

  • A1082 读数字

  • A1016 电话账单(熟悉日期计算,时间计算差值,利用hadPrint标记是否输出)

  • A1095 校园内的车(map的使用以及时间匹配,时间表示)

  • P117 n皇后问题回溯

  • P122贪心区间问题

  • A1033 油箱问题,贪心算法。

  • A1038 字符串组合为最小数,注意cmp函数的写法,string类型的应用

  • A1085 对于一个数列,查找M<=m*p的最长子数列。注意使用二分法upper_bound().

  • A1010 寻找最小进制数,使得两数相等,注意使用ll数据类型,上下界的确定,以及将多进制转化为十进制的运算,二分法应用。

  • A1044 P173 查找和大于或小于S的子数列。注意sum[]递增数列的应用,子数列[i,j]的和为sum[j]-sum[i-1]。同时注意upper_bound()的使用,以及nearS的求解。

  • A1093 有几个PAT 用数组统计A左边的P个数,统计A右边的T个数,相乘的和即为所求

  • A1049 [0,n]以内的数字的1的个数。寻找对于每一位,当取1时,可以有多少种情况,学会使用left、right、mid。(同理与数列片段和A1104求每一位上,可能的情况)对于mid=0、1、else找出规律

  • A1039 P1039学生与选课 给出每门课上的学生姓名,求每个学生所选的课。由于又一轮数据较大,使用string和map会超时,可以将姓名进行hsah求解,M=26*26*26*10+1;学生选择的课程编号为vector<int> course[M]

  • A1047 P235与上题类似,本题目是给出学生的选课,输出每门课的学生,使用vector<int> course[maxc]//存放第i门课的学生编号学生编号与学生姓名相对应char name[maxn][5]

  • A1060 P241 科学计数法string应用

  • A1022 P255 使用map<string, set<int> > mp;string和map传递参数较慢,尽量使用引用来调用参数;对于关键字的读入while(cin>>key){ mpKey[key].insert(id); c=getchar(); if(c!='\n') break; }

词汇

polynomial 多项式
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值