算法笔记 心得7
1,cin,cout
为C++的输入输出函数,使用时需添加头文件”#inlcude<iostream>””using namespace std;”
如果需要一整行,则需要使用getline函数
eg,
char str[100];
cin.getline(str,100);
如果是string容器,则需要下面的输入方式:
string str;
getline(cin,str);
cout的换行方式:
cout<<n<<“\n”<<db<<endl;
如果想要控制double型的精度,例如控制输出小数点后两位,那么需要在输出之前加上#include<iomanip>
eg,输出123.46
cout<<setiosflags(ios::fixed)<<setprecision(2)<<123.456<<endl;
推荐使用C语言的scanf与printf函数进行输入/输出,只有在(string)时才使用cin与cout
2,浮点数比较
经过大量计算后,浮点数的存储不总是很精确(会比比较操作带来极大的干扰),需要引入一个极小数eps来对这种误差进行修正。
等于运算符(==)
经验表明,eps取10^-8是一个合适的数字——对于大多数情况不会漏判,也不会误判.
将eps定义为常量1e-8;
const double eps=1e-8;
为了使用比较更加方便,把比较操作写成宏定的形式:
为了比较更加方便,把比较操作定义写成宏定义的形式:
#define Equ(a,b) (fabs((a)-(b)))<(eps))
大于运算(>)
#define More(a,b) (((a)-(b))>(eps))
小于运算符(<)
#defien Less(a,b) (((a)-(b))<(-eps))
大于等于运算符(>=)
#define MoreEqu(a,b) (((a)-(b))>(-eps))
小于等于运算符(<=)
#define LessEqu(a,b) (((a)-(b))<(eps))
3,pi
由于cos(pi)=-1知pi=acos(-1)
const double Pi=acos(-1.0);
⚠️:由于精度问题,在经过大量计算后,可能一个变量中存储的0是一个很小的负数,如果开根号,就会出现不在定义域内而出错。这种情况就需要使用eps使变量保证在定义域内。
⚠️:在某些编译环境产生的原因下,本应该为0.00的变量在输出时变成-0.00,这是编译器环境本身的bug,只能把结果存放在字符串中,然后与-0.00进行鬓角如果对比成功,则加上eps来修正为0.00
4,时间、空间、编码复杂度
O(cn^2):c为时间复杂度的常数,如果常数比较大,会导致即使时间复杂度相同(讲时间复杂度时一般是不带系数的),其性能也会有比较大的差别
一般有O(1)<O(logn)<O(n)<O(n^2)
对数复杂度书写一般省略底数
⚠️:对于一般的OJ系统来说,一秒能承受的运算次数大概是10^7~10^8
时间复杂度:算法要执行基本运算的次数所处的等级
空间复杂度:算法需要消耗的最大数据空间
编码复杂度:。。。(暂无定性的概念)
4,黑盒测试
定义:系统后台会准备若干组输入数据,然后让提交的程序去运行这些数据,如果输出的结果与正确答案完全相同(字符串意义上的比较),那么就称通过了这道题的黑盒测试
根据黑盒测试是否对每组测试数据都单独测试或是一次性测试所有的数据,又可以分为单点测试和多点测试
单点测试:
系统会判断每组数据的输出结果是否正确,如果输出正确,那么对改组数据来说就通过了测试,并获得这组数据的分值。
多点测试:
多点测试要求程序一次能运行所有数据,并要求所有输出结果都必须完全正确,才能算作这题通过;只要有其中一组数据的输出错误,本题就只能得0分。
(1)while…EOF型
当题目没有说明多少数据需要读入时,就可以利用scanf的返回值是否为EOF来判读输入是否接结束。
while(scanf(“%d,&n” != EOF){
….
}
代码含义:只要scanf的返回值部位EOF(即文件中的数据没有读完)就反复读入n,执行while函数体的内容,当读入失败(到达文件末尾),结束while循环。
⚠️:当读入失败时,scanf函数会返回-1而不是0,C语言中使用EOF(End Of File)来代表-1
scanf函数的返回值为其成功读入的参数个数
(2)while…break型
上一种的延伸,题目要求满足某个条件时停止输入
eg,当输入的两个数a和b都为0时结束输入。
while(scanf(“%d%d”,&a,&b) != EOF){
if(a==0&&b==0) break;
}
写法,把退出条件的判断放入while语句中,令其与scanf用逗号隔开,
while(scanf(“%d%d”,&a,&b),a||b){
}
a|| b 等价于 a!=||b!=0
(3)while(T--)型
这种类型中,题目会给出测试数据的组数,然后才给出相应数量组数的输入数据
eg,
while(T--){
s canf(“%d%d”,&a,&b);
}
(1)正常输出
(2)每组数据输出之后都额外加一个空行(只需要在每组输出结束后额外 输出一个换行符\n即可)
(3)两组输出数据之间有一个空行,最后一组数据后面没有空行
这一般是在第三输入类型while(T--)的情况下,只需要判断T是否已经减小到0来判断是否应当输出额外的换行。
eg,
scanf(“%d”,&T);
while(--){
int sum=0;
scanf(“%d”,&n);
….
printf(“&d\n”,sum);
if(T>0) printf(“\n”);
}
输出一行N个整数,美两个整数之间用空格隔开,最后一个整数后面没有不允许加上空格。
eg,
for(int i=0;i<n;i++){
printf(“%d”,a[i]);
if(i<N-1) printf(“ “);
else printf(“\n”);
}
⚠️:在多点测试中,每一次循环都要重置一下变量和数组,否则在下一组数组来临的时候变量和数组的状态就不是初始状态了。(如上面的sum=0就必须放在while内,如果放在之外,则第二组数据来临时sum就不是0了)
重置一般使用memset函数或fill函数。