📡1.2 cin与cout
cin
cin的输入输出速度实在是太慢,所以在考试的时候完全不推荐cin来作为输入。
但是之前说过gets被禁用了。gets_s 在c++中又不允许使用,所以我们偶尔需要用cin.getline来读入字符串。
cin.getline(str,1000);的形势读入字符串的时候需要记得#include<iostream和using namespace std;
还有就是如果读入的是将字符串读入string容器(之后会讲)的话是下面这种形式
string str; getline(cin,str);
cout
完全不推荐0.0
🎚1.3 浮点数的比较
由于计算机中采用有限位的二进制编码,因此浮点数在计算机中的存储并不总是精确的。下图是float和double的二进制存储。
**在经过大量计算之后,浮点数发生改变。**例如:3.14可能变成3.13999999999或者3.14000000001,这种情况下浮点数就不能使用(==)来判断是否相等了。
一般的做法是引入一个极小数eps来对这种误差进行消除。根据经验表示eps选择1e-8(10-8)比较合适。
那么对应的判断相等和大于小于和大于等于小于等于呢?
我给大家做了个总结的图,记住图就会写代码。
附上宏定义的写法:
const double eps = 1e-8; const double pi = acos(-1.0); #define Equ(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 LessEqu(a, b) (((a) - (b)) > (eps))
记不住建议就画图 然后对照图些就好了
🥩1.4 复杂度
一般来说复杂度都包含时间复杂度和空间复杂度和编码复杂度。
🍔1.时间复杂度
时间复杂度指的就是需要执行的基本运算的次数所处的量级
for(int i = 0;i < n;i++) sum += a[i];
这个for循环的复杂度就是O(n)。
for(int i = 0;i < n;i++){ sum += a[i]; sum += a[i]; }
上面的量级就是在2n,但是两者都是随数量级线性增长的,所以一般我们认为O(2n)与O(n)等价。
for(int i = 0; i < n;i++) for(int j = 0;j < n;j++) sum += a[i][j];
上面的基本操作就是量级在O(n2),其消耗的时间随n的增大而呈现平方级增长。
在时间复杂度中,高幂次会吸收低幂级的复杂度
例如:我们认为O(3n2 + n = 2) = O(3n2) = O(n2)。
我们把3这个常数叫做时间复杂度的常数,有些算法比较复杂的时候。可能会出现卡常数的情况,但是一般不带常数讨论复杂度。
对于OJ来说,一秒能承受的运算次数啊大概在107 ~ 108
因此,O(n2)的算法对于n规模为1000可以接受,但是n为100000时间是不可以接受的。
对于不同形式的复杂度的比较:记住五个字常对幂指阶
也就是考研常说的比大小的问题。从前往后复杂度依次升高
🍟2.空间复杂度
与时间复杂度对应的就是空间复杂度,主要取决于开的数组大小一般来说空间不超过100m都是可以接受的,大概对应的数组就是107以上的大小
🌭3.编码复杂度
这是一个定性的概念,如果算法过于冗长就会产生比较长的编码,代码量就比较巨大。
所以大家要用函数去做一些重复的事情,有利于降低编码复杂度。
🥚1.5黑盒测试
黑盒测试是指:系统后台会准备若干测试数据,然后让提交的程序就跑,如果输出的答案与正确答案完全相同(字符串层面的比较) 就通过了黑盒测试,否则返回对应的错误。其中分为单点测试和多点测试。
🥙1.单点测试
所谓的单点测试就是系统会判断每组数组就是正确,如果通过这组数据就算通过了一组数据,获得对应的分数。PAT和洛谷都是采用的这种形式。这种情况下只需要保证一遍程序的执行就可以了。
举个例子:
#include<cstdio> int main(){ int a, b; scanf("%d %d", &a,&b); printf("%d\n",a + b); return 0; }
这种就是执行完一组数据程序就会正常返回。
🥗2.多点测试
多点测试要求程序一次性运行完所有的数据,否则就是不通过。部分在线评测系统(codeup)采用这种方式。
对于多点测试我们需要知道什么时候程序输入结束。基本上有三种读取方式分别介绍。
2.1while …EOF型
这种题一般不知名何时输入结束,我们就要利用结束符判断程序的结束。
当读到文件结束符的时候,scanf函数会返回EOF
所以我们可以这么写:
while(scanf("%d %d",&a,&b) != EOF){ ... }
给个例子
#include<cstdio> int main(){ int a, b; while(scanf("%d %d", &a, &b) != EOF) printf("%d\n",a + b); return 0; }
在我们平常测试的时候并不会触发EOF状态。因此如果想要在调试框内手动触发EOF,可以按Ctrl + Z组合键,屏幕上会显示^Z,按Enter就可以结束了。
2.2while…break型
这种适合当a、b都是0时结束输入
#include<cstdio> int main(){ int a, b; while(scanf("%d %d", &a, &b),a || b){ printf("%d\n",a + b); } return 0; }
2.3while(T–)型
这种题目会在一开始给出数据的数量,标准模板如下:
#include<cstdio> int main(){ int T, a, b; scanf("%d", T); while(T--){ scanf("%d %d", &a, &b); printf("%d\n",a + b); } return 0; }
再给一个要求两组数据之间有一个空行,最后一组数据后面没有空行
while(T--){ int sum = 0; scanf("%d", &n); for(int i = 0;i < n;i++){ scanf("%d", &a); sum += a; } printf("%d\n",sum); if(T > 0) puts(""); }
最后要说明:
在多点测试中,每一次循环都要重置一下变量和数组,否则下一组数据来临的时候就不是初始状态了,一般使用memset和fill函数来进行。
根据要求灵活修改判断条件格式化输出(不要担心后面会有更多的练习)
🐳课后习题
今天的题目难度也不高,有点多,我写完会放题解,大家写完了可以在评论区打卡哟!题解我放评论区吧,这样不用修改文章。(大家有问题可以联系我,今天太晚了,题解可能会鸽两题 咕咕咕)
题目
2.8小节——C/C++快速入门->结构体(struct)的使用
2.10小节——C/C++快速入门->黑盒测试
题解:评论区见,置顶没有就是我没写完0.0,大佬们刷完打个卡