目录
模板框架:
基本框架
#include<bits/stdc++.h>
using namespace std;
int main()
{
while(~scanf() )或while(scanf()!=EOF) //※※题目要求多组测试用例时必须加while ※※(~为取反操作,EOF为-1)
{
printf();
}
//scanf 的输入速度比 cin 快得多,推荐使用scanf与printf进行输入输出,且不要与cin/cout混用,否则输入或输出结果可能会出紊乱问题。
return 0;
}
//在一行连续输入未知个数的数据,回车结束
#include<bits/stdc++.h>
using namespace std;
int main()
{
int a[1003],n=0;
int x;
while(cin>>x)
{
a[n++]=x;
if(getchar()=='\n')break;//利用getchar()判断输入数据之后的字符是否为换行符,即’\n’。
}
for(int i=0;i<n;++i)
{
cout<<a[i]<<" ";
}
return 0;
}
※return 0;
※※#include<bits/stdc++.h>
DFS不易混乱的敲码思路:
int DFS(int x,int step,int n)
{
//进入DFS的该x状态是满足条件的即程序已经处于该X状态
//如果该x状态即最终要找的状态则结束并输出结果
//该x状态已经没法满足条件了,return
//如果不满足上述条件,则遍历该x状态之后的所有状态,
//并DFS满足条件的下一种状态
}
求char数组的长度:
函数原型:unsigned int strlen(char *s);
头文件:#include <string.h>;
参数说明:要计算长度的字符串数组的首地址;
功能:计算给定字符串的(unsigned int型)长度,不包括'\0'在内;
对结构体排序:
①sort(start,end,cmp)
参数
(1)start表示要排序数组的起始地址;
(2)end表示数组结束地址的下一位;
(3)cmp用于规定排序的方法,可不填,默认升序,可重载运算符
例:
int cmp(结构体名 a,结构体名 b)//实现结构体按h从大到小排序
{
return a.h>b.h;
}
②结构体内重载小于号运算符(不能重载大于号)
bool operator <(const 结构体名 &a) const
{
return h>a.h;
}
附上两个链接:
http://blog.moertel.com/posts/2013-05-11-recursive-to-iterative.html,教你如何把recursion(递归)转为iteration(迭代)。
https://medium.freecodecamp.org/follow-these-steps-to-solve-any-dynamic-programming-interview-problem-cc98e508cd0e,教你动态规划的解题套路。
编程经验与注意事项:
若题目要求时间限制为1s即1000ms,则算法复杂度不能超过一千万即10^7。即若算法复杂度为O(n^2),则n不能超过3000,否则需要换复杂度更低的算法。若时间限制不是1000ms则根据1000ms的最大复杂度进行类推。空间大小一般为2^26B即65536KB,可根据给出的空间大小的限制计算不同类型数据所能申请数组的最大长度(short:16位即2B,int:32位即4B,long long:64位即8B;float:32位即4B,double:64位即8B;char:8位即1B);若为int数组,则65536KB最大可开辟2^24即1.6*10^7个。(1B=2个16进制数=8bit(位))
用右移运算符代替了除以2,用位与运算符 x&1 代替了求余运算符 x%2==1 来判断一个数是奇数还是偶数,同x%2==1,1为奇数0为偶数,用时加括号如(x & 1)。位运算的效率比乘除法及求余运算的效率要高很多。
指针变量必须先赋值,才能正常使用,故创建结构体指针后,在对该指针所对应结构体的数据进行操作前必须要给该指针所指结构体变量赋值,可以把一个已有指针赋给它或是用new 结构体名,或(结构体名*)malloc(sizeof(结构体名));给指针申请一个空间,new与delete搭配,malloc()与free()搭配。使用格式区别:delete 结构体名;free(结构体名);//因为new与delete是操作符,而malloc()与free()是库函数。
break只能跳出一重循环,利用goto可以跳出整个循环,或用标记变量break一层一层跳出循环;continue是结束此次循环进行下一轮循环。
goto g;
g: ........;
※while (fabs(a-b)<1.0E-7) //判断两个浮点数a、b是否相等
浮点数判断两个数相等不能直接使用 == 运算符,要相减后判断其绝对值小于1.0e-6即0.000001或1.0e-7, 一般就认为它们是相等的了(因为浮点数表示存在精度问题,完全==比较难,但是判断斜率等需要高精度的值是否相等时可直接用==判断)。
精度应至少比题设要求精度多一位(不超时的情况下可以精度更高),因为题设精度下一位的大小会影响四舍五入的情况,而下下位则影响不到该位。
结构体的初始化类似于常规数据类型数组的初始化,可作为全局变量初始化或作为局部变量定义时初始化(全局变量默认值为0或NULL,局部变量默认值随机),也可用memset对结构初始化,但memset只能将结构体所有数据变量初始化同一值。
关键字与库函数相关:
C/C++ 中 NULL、'\0'、'0' 、0及空格的区别
1、NULL即空指针。在C中,NULL是指向0的指针,由 #define NULL ((void *)0)定义;在C++中,NULL就是0,由 #define NULL 0 定义。可参见 vs2013 的库文件 string.h。
2、'\0' 是空字符常量,表示字符串的结束,ASCII码值为0。
3、0是数字0。当其转换为字符变量时,相当于ASCII码为0的字符,即空白符'\0'。
4、'0'是字符0,ASCII码值为48。
5、空格是可显示字符空格,ASCII 码值为32。
注意:
给指针置位为空指针时,应该使用 NULL;
给字符串添加结束标志时,应该使用 '\0' ;
空字符串""中每个元素都是空白符'\0'。
NULL是代表空的关键字,而null并不是关键字,null在C/C++没有声明跟定义。
It is impossible to use functions from the header file math.h for integer parameters(即仅适用于浮点型). For example, this code will not be compiled: sqrt(2). It is correct to write sqrt((double)2) or sqrt(2.0).
The constant M_PI is not supported. You have to define it yourself. For example, use const double PI = acos(-1.0).
int abs(int i); // 对int型数据取绝对值,头文件是<stdlib.h>
double/float fabs(double/float i); //对浮点型数据取绝对值,头文件是是<math.h>
memset(a,n (int),sizeof(a));//初始化函数,具体注意事项见信息学奥赛书
__gcd(x,y);//求最大公约数,x、y必须是相同数据类型的整型数据,头文件是<algorithm>
最小公倍数=x*y/最大公约数;
编程题考察知识点:
闰年:能被400整除或能被4整除但不能被100整除的年份
闰年2月29天,共366天;
平年2月28天,共365天
英文26个字母。
所有构造得到的中间结点(即哈夫曼树上非叶子结点)的权值和即为该哈夫曼树的带权路径和。
数学知识点:
一个三角形,边长分别为a、b、c,三角形的面积S可由以下公式求得: S=sqrt(p(p-a)(p-b)(p-c))。
公式中的p为半周长: p=(a+b+c)/2
a%b:其中变量 a,b 必须为整型变量,而不能为浮点数。且 b 变量必须为非零值,否则会出现模零错误,程序会因为该异常意外终止,在评判系统中表现为评判系统给出了运行时错误。
即若 a 为正数,则a%b必为非负数(可能为 0);若 a 为负数,则a%b结果必为非正数(可能为 0)。而表达式结果与b 的符号没有直接关系,即 a % -b 与 a % b 的结果相同,例:负奇数%2=-1并不是正1。为了避免出现负余数我们只需在该数上加上模数取余即可,即a%b变为(a+b)%b。
(a*b)%c=((a%c)*(b%c))%c; //避免大数运算的溢出问题
(a+b)%c=((a%c)+(b%c))%c;
快速幂取模:
a^b mod c = (a*a)^(b/2) mod m , b为偶数
a^b mod c = (a*(a*a)^(b/2)) mod m , b为奇数
分数取模:
小费马定理:a^(p-1) % p = 1 mod p对这个定理稍稍改动一下:a^(p-2) % p = a^-1 % p,所以 (x/y) % p = x∗y^(−1) % p= x∗y^(p−2) % p。
若 a、b 其中之一为零,则它们的最大公约数为 a、b中非零的那个(因为0除以任何数都能整除)
复数的模:复数的实部与虚部的平方和的正的平方根的值
数据类型表示范围: 奥赛书p25
编程语言自带数据类型的有效十进制数最大值为19位数,即long long类型
※int(long)
4字节8位可表达位数:2^32=42 9496 7296
范围:-21 4748 3648 ~ 21 4748 3647 (2.1*10^9) 因为2^10≈10^3
int最大值表示:0x7fffffff(int 32位,8个16进制位,1个16进制位占4个二进制位)或用memset(a,0x7f,sizeof(a))初始化数组(为0x7f7f7f7f略小于0x7ffffffff)(memset只能按字节初始化,一字节两个16进制位)
unsigned int(unsigned long)
4字节8位可表达位数:2^32=42 9496 7296
范围:0 ~ 42 9496 7295 (4.2*10^9)
※long long (__int64)
8字节8位可表达位数:2^64=1844 6744 0737 0960 0000
范围:-922 3372 0368 5477 5808 ~ 922 3372 0368 5477 5807 (9.22*10^18)
unsigned long (unsigned __int64)
8字节8位可表达位数:2^64=1844 6744 0737 0960 0000
范围:0 ~ 1844 6744 0737 0955 1615 (1.844*10^19)
※double:
8 byte = 64 bit
范围:-1.7 E+308 ~ 1.7 E+308(最大有效数10^15,比long long少3位)
long double:
16 byte = 128 bit
范围:-3.4 E+4932 ~ 1.1E+4932(最大有效数10^18)
输入输出相关:
读取输入数据直到文件结束:(数字、字符、字符串)
ios::sync_with_stdio(false); //关闭不同输入输出方式的同步,可以加快cin/cout速度,但是速度还是不如scanf/printf快,且关同步后不同类型的输入输出方式不可以混用,例:cin/cout不可以与scanf/printf 、getchar()/puts() 等其他输入输出方式混用。
字符/字符串输入输出:
△多次输入且用到scanf("%c",&c);或gets();时注意:
char a , c;
scanf("%c",&a);
scanf("%c",&c);或getchar();
//用scanf输入单个字符时,后一次的输入会吃前一次输入结尾的空格或回车(因为scanf("%c",&c);可以接收回车、空格等任意单字符),解决方案是scanf(" %c",&c)即在%c前加个空格用来吸收上次输入结尾的空格或回车或是用getchar()吸收这个字符。
输入字符:
char ch;
cin>>ch //只能输入非空格非回车字符
△scanf("%c",&ch);//可以输入任意字符(包括空格、回车)
△ch = getchar();//可以输入任意字符(包括空格、回车),作用与scanf("%c",&ch);完全相同
输出字符:
cout<<ch;//输出一个字符
printf("%c",ch);//输出一个字符
putchar(ch);//输出一个字符
输入字符串:(cin与scanf("%s",)输入字符串时都不能接收空格跟回车)
char buf[100];
△scanf("%s",buf);//输入字符串,以空格、回车结束(%c输入单字符时可接受任意字符)
△gets(buf);//输入一个字符串,可以包含空格,以回车结束,不支持string,可以吸收掉回车符,结尾加'\0' ,
cin>>buf;//输入字符串,以空格、回车结束
cin.get(buf,100)//输入一个字符串,不支持string,可以包含空格,以回车结束,保留结束符
cin.getline(buf,100)//输入一个字符串,不支持string,可以包含空格,以回车结束,清除结束符
△getline(cin,buf)//输入一个字符串,支持string,可以包含空格,以回车结束,清除结束符,不会吸收回车符。
(首先考虑scanf("%s",)与gets(),因为速度快,其次再考虑其他输入方法。)
输出字符串:
printf("%s",buf);//输出char字符串
△printf("%s",buf.c_str());//输出string字符串
puts(buf);//向屏幕输出字符串,并换行
cout<<buf;//输出字符串
输入输出string类型字符串:
scanf 是 C 语言的函数,string类型变量无法直接用scanf/printf进行输入/输出,输入则需要借助char数组, 可以借助c_str()函数进行输出。
例:
string s;
char ss[5000];
scanf("%s",ss);
s=ss;
printf("%s\n",s.c_str());
(c_str()的作用是返回一个C风格的字符串临时指针,可通过strlen(ss)计算char数组中字符串的长度,不包括'\0'在内)。
整形数据输入输出:
※格式化输入问题:
※①scanf("%d:%d:%d",&x,&y,&z); //引号中为输入数据的格式,后面即可直接分离出数据,例:2013:4:12可直接分离出x=2013、y=4、z=12
②string s="2013:4:12";
sscanf(s.c_str(),"%d:%d:%d",&x,&y,&z); //可以分离出字符串s中的数据(可参考《ACM程序设计》P35)s.c_str()的作用是返回一个C风格的字符串临时指针
③20110412 无空格等分隔符格式,scanf ("%4d%2d%2d",&x,&y,&x);//使用长度控制符进行输入赋值。
long long(__int64)类型
64位整数须用“%I64d”(“%lld”可能也可)输入输出。