一、小知识点
1、头文件问题
#define x first //宏定义
#define y second
typedef pair<int, int> PII; //二维组习惯用pair存,typedef可以数据类型重定义
typedef long long LL; // typedef可以数据类型重定义
const int N = 500010; //定义常量,比#define安全
若只用到scanf()和printf()可以只写 cstdio,不写 namespace
iostream 中有<string>头文件,有abs()绝对值函数
因为c++标准一直在更新,一些在cmath里的函数在iostream里直接被包含了
cmath 中有sqrt()
c++里max和min函数被<algorithm>和<iostream>同时包含了
<string.h>、<cstring>、<string>三者关系
1、c++的<cstring>兼容c的<string.h>,而<string>是c++标准模板库(STL)中的内容,可以定义string 对象,
如string str="acwing",使用string相关函数。<cstring>和<string>不同。
2、string.h,是C风格字符串操作的一个函数库,strlen,strcpy,strcat,strcmp,puts……都在这里面了。
3、string,是C++定义的std::string所使用的文件,是string类的头文件,属于STL范畴,
包含substr(),length(),size(),insert(),find(),replace(),erase()等函数。
const可以写在函数内部
2、变量相关
bool false/true 1 byte
char 'a'、'c' 1 byte
int -2147483648~+2147483647 4 byte int的最大值是个以二开头的十位数
long long [int] -9223372036854775808 ~+9223372036854775807 8 byte long long的最大值是一个以9开头的十九位的数
float 1.23 2.63 4 byte 6-7位有效数字
double 3.123456789123 8 byte 15-16位有效数字
long double 12byte 18-19位有效数,很少用到
写算法99%的情况会用double不用float,因为float精度6-7位,double精度15-16位,位数有300多位,有些LL相乘,也可以用double。
c++中 double也可 自增,如1.2 自增 变为2.2
3、输入输出相关
scanf("%*d%d%d", &n, &m); //忽略第一个整数的读入方法
scanf("A = %d, B = %d",&a, &b); // f代表格式化输入输出
scanf("%d\n%c") //读入跨行的数字和字符
scanf() 不能一次读入一个整数数组,只能一个一个读
string 只能用cin 来读,不能用scanf
scanf("%d%d %c",&a,&b,&c); //%d 后加个空格,防止把空格当字符读入
cin >> a >> b >> c; //cin会自动过滤空格
关于整行读入问题
gets()函数在新版C++中被移除了,因为不安全。
//第1个函数:fgets(),只能读入到字符数组中
//fgets不会删除行末的回车字符,也就是说
//你输完一行 点击回车时, 会把回车读进来,用cout输出str字符数组时,光标会停在 下一行;
//你输完一行 不点击回车时,不会把回车读进来,用cout输出str字符数组时,光标会停在 本行末尾;
fgets(str字符数组,读入个数size, stdin); //注意最多读入size-1个到字符数组str中
//第二个函数:getline()
//读入到字符数组和string字符串中, getline写法不同。读入整行到string中,只能用getline
string s;
getline(cin,s);
char c[100];
cin.getline(c,101); //注意最多读入100个到字符数组或string中
cin >> str; // 输入字符串时,遇到空格或者回车就会停止
cout << str << endl; // 输出字符串时,遇到空格或者回车不会停止,遇到'\0'停止
while (cin >> x && x) //while (cin >> x, x) //在条件表达式中,逗号表达式的值等于最后的值
不告诉个数时,统计输入数据的个数时,循环判断条件可写为 while(scanf(“%d”,x) != -1) cnt++;
//或者 while(scanf(“%d”,x) != -1) cnt++;
c++中EOF 为-1
对应的占位符
int : %d
float : %f
double : %lf
char : %c
long long : %lld
C++中取模结果正负只与%前面的数的正负有关系
cout << 5%2 << endl; 输出 1
cout << 5%-2 << endl; 输出 1
cout << -5%2 << endl; 输出 -1
cout << -5%-2 << endl; 输出 -1
C++中除法是向0取整
cout << 5/2 << endl; 输出 2
cout << -5/2 << endl; 输出 -2
C++中强制类型转换是向0取整
cout << (int)2.5 << endl; 输出 2
cout << (int)-2.5 << endl; 输出 -2
printf("%-5d",23); //%-5d向左对齐,%5d向右对齐
printf("%8.3f",23.44); //%8.3f 表示这个浮点数最小宽度为8,保留三位小数,宽度不足时前面补0.
printf("%.0lf ", 0.15 * 100); //保留0位小数,输出15
printf(%s,str_arr);//str_arr为存有字符串的数组,则输出字符串结束标记'\0'前的内容.同cout
%%输出%,比较特殊的转义
不能用printf直接输出string,需要写成:printf(“%s”, str.c_str());或者puts(str.c_str());
cout可以输出带有空格的字符数组、字符串和string,puts能输出char类型字符数组或字符串,不能输出string类型
4、数组初始化
int c[5] = {0, 1, 2}; // 函数里未被初始化的部分为0. 等价于c[] = {0, 1, 2, 0, 0} ,
int a[5] = {0}; // 全部为0
char a1[] = {'C', '+', '+'}; // 列表初始化,没有空字符
char a2[] = {'C', '+', '+', '\0'}; // 列表初始化,含有显示的空字符
char a3[] = "C++"; // 自动添加表示字符串结尾的空字符
char a4[6] = "Daniel"; // 错误:没有空间可以存放空字符
char str[5]={'s','s','d'}; //还是一个字符串
5、函数相关
函数声明可写在main中。如 int fun(int);
strcpy这个函数只能给char数组赋值,string直接用+=即可
fabs() 是浮点数求绝对值,abs()是整数求绝对值
sort()函数是插入排序和快排的结合,数据个数小时用插入排序,大时用快排
swap函数,在<algorithm>中,可以交换任意类型
str.substr(string串开始下标,[长度]);//返回string字符串
strlen 等函数只能用于 字符数组或字符串,不能比较string。
//为什么编译器会报错
//min 比较的时候得是两个相同的类型,string的size,的返回值类型是size_type,强转一下int就可以了
int len=0;
string str="adsd";
len = min(len, str.size());//报错
有返回值的函数可以不写return, 会返回随机值;
函数内的static静态变量相当于在函数内部开了一个只有该函数能用的全局变量,有默认值,如0,储存在堆中,这样
可以避免一定的重名问题;
多维数组传参时,只有第一维的长度可省略不写,这个和数组内部实现方式有关,且后边的维数的长度需和形参大小相同;
数组不能给数组赋值,可以使用<cstring>中的memcpy(要填充的数组b,被复制的数组a, 元素个数* 4);
inline 函数,在被调用的地方,换成函数体内的代码,对递归函数在时间效率上不明显。
void swaps(int &a,int &b);//函数声明要和函数定义的第一行保持一致,包括引用符号
6、算法相关
判断闰年方法
闰年分为普通闰年和世纪闰年,其判断方法为
公历年份是4的倍数,但不是100的倍数,为普通闰年;
公历年份是整百数,且必须是400的倍数,为世纪闰年。
归结起来就是:四年一闰;百年不闰;四百年在闰。
if(year%400==0||year%4==0&&year%100!=0)
cout<<"yes"<<endl;
else
cout<<"no"<<endl;
秦九韶算法 求p^0+p^1+...+p^n ,时间复杂度O(N)
LL calc(string n, LL r)// 秦九韶算法求r进制转换为十进制(递推思想)
{
LL res = 0;
for (auto c : n)
{
res = res * r + get(c);
}
return res;
}
int get(char c) //获取36进制下字符c代表的数字
{
if (c <= '9') return c - '0';
return c - 'a' + 10;
}
//打印100以内所有质数
#include <iostream>
using namespace std;
int main()
{
for (int i = 2; i <= 100; i ++ )
{
bool is_prime = true;
for (int j = 2; j < i; j ++ )
{
if (i % j == 0)
{
is_prime = false;
break;
}
}
if (is_prime) cout << i << endl;
}
return 0;
}
//判断一个数是不是质数
bool is_prime(int n)
{
if (n == 1) return false;
for (int i = 2; i * i <= n; i ++ )
if (n % i == 0)
return false;
return true;
}
曼哈顿距离:|x1-x2|+|y1-y2|,可用于打印菱形或者方格相关问题
欧几里得距离:sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2))
//第一类双指针算法
//如统计字符串中最长的连续的相同字符
string str;
cin >> str;
int cnt = 0;
char c;
for (int i = 0; i < str.size(); i ++ )
{
int j = i;
while (j < str.size() && str[j] == str[i]) j ++ ;
if (j - i > cnt) cnt = j - i, c = str[i];
i = j - 1;
}
cout << c << ' ' << cnt << endl;
7、技巧相关
~i 表示 对i二进制取反,i=-1的时候,取反刚好是0
string 可以做的char a[]不一定能做,80%用string
8、课外知识
外存和内存进制不一样,外存是10的3次方,如硬盘,内存是2的10次方
网线带宽 8Mb=1MB(实际上)
99%的评测器会自动过滤掉程序最后的一个回车和每一行末尾的多余空格,但是PAT不是
9、结构体---
结构体排序方法参见我的《结构体排序的四种方法【推荐】》这篇分享
//结构体类型定义:固定大小空间的内存块
struct teacher
{
char name[62];//64
int age;//4
};
void main()
{
//结构体变量的定义及初始化
//在c编译环境下和.cpp环境下变量定义方法有所区别
//struct teacher t1;//C语言需要加上struct关键字
//teacher t2;//C++中则不必
struct teacher t1={"daiwen",22};
//结构体变量作为函数的参数时,若需要修改 结构体变量,则函数的形参要加上指针或引用
//结构体数组作为函数的参数时,若需要修改 结构体数组,则函数的形参写成
//struct Teacher *tarray 或struct Teacher tarray[]来接收 结构体数组即可
}
10、同学们补充知识点(非常感谢!!!)
1、字符‘0’~‘9’转数字就是减‘0’,例如:ch=‘3’,n=ch-‘0’,n就会被赋值为整数3。
2、取个位使用对10取余(%10),取每一位数字可以在循环中先对10取余(%10)再除以10(/10)。
例如:n=123,在循环中使用a=n%10,n=n/10,就可以让a分别取到3,2,1
3、交换两个变量的值,不一定需要第三个变量,可以用表达式计算,例如:a=2,b=3,交换a和b的值,
可以用a=a+b,b=a-b,a=a-b,一套操作下来,a和b的值就交换啦!
语法基础课 比较难点的或有技巧的题
655 天数转换 //技巧
656 钞票和硬币 //技巧 小数没有取余运算,本题先把小数变为整数
725 完全数
726 质数
727 菱形 //技巧
753 平方矩阵I //找规律
754 平方矩阵II //找规律
756 蛇形矩阵 //技巧
760 字符串长度 //注意:fgets函数会把回车也读进来,getline不会
763 循环相克令 //技巧
773字符串插入
766 去掉多余的空格
770 单词替换
823 排列 //难
二、STL 总结
ASCII 表
常用ASCII值:'A'- 'Z'是65 ~ 90,'a' - 'z'是97 - 122,0 - 9是 48 - 57。
局部变量(存放在栈中,内存限制为1M)数组,如果定义为赋值,则数是随机的,可以int a[100000]={0},保证全部数组值为零。。。大型数组一般定义在全局变量,存放在堆中,没有内存限制,且只要定义,默认所有元素初始值为零
同学,总结的不错,给你点个赞!如果数组大小较大(大概10^6级别),则需要将其定义在主函数外面,否则会使程序异常退出,原因是函数内部申请的局部变量来自系统栈,允许申请的空间较小;而函数外部申请的全局变量来自静态存储区,允许申请的空间较大。
我也补充几个:
1、字符‘0’~‘9’转数字就是减‘0’,例如:ch=‘3’,n=ch-‘0’,n就会被赋值为整数3。
2、取个位使用对10取余(%10),取每一位数字可以在循环中先对10取余(%10)再除以10(/10)。例如:n=123,在循环中使用a=n%10,n=n/10,就可以让a分别取到3,2,1
3、交换两个变量的值,不一定需要第三个变量,可以用表达式计算,例如:a=2,b=3,交换a和b的值,可以用a=a+b,b=a-b,a=a-b,一套操作下来,a和b的值就交换啦!
王兆松你好,看你整理的内容非常用心,非常好,向你学习!
想问一下,你整理完这个是多大年龄?
自己顶一顶!
同学补充的很好!我给这三个知识点也补充进去,谢谢同学!
另外我今年刚好18哦~
明白,你是高三写的总结,现在上大学了
兄弟真秀!
谢谢,hh
有收藏功能吗
这篇分享开头的左边的⭐是收藏
大佬牛b
谢谢大佬的夸奖 哈哈哈
好人一生平安!
大家互相进步!哈哈哈 整理笔记也方便我以后复习
感谢大佬帮助,受益匪浅
谢谢同学!一起加油!
谢谢同学,一起加油!
“写算法99%的情况会用double不用float,因为float精度6-7位,double精度15-16位,位数有300多位,有些LL相乘,也可以用double。”
问:不是有效位数吗?为什么说300多位?
这个我目前也还没搞清楚,等我弄明白了再来解惑
秀啊 大佬
感谢大佬的帮助
ORZ
秦九韶算法那里int get(char c) //获取36进制下字符c代表的数字
{
if (c <= ‘9’) return c - ‘0’;
return c - ‘a’ + 10;
}是什么意思啊,没看太懂
36进制就是用数字0~9代表数字0~9,用字母A~Z(或a~z)表示数字10~35,比如‘d’-‘b’等于2,差值为ascii的差值
那这一步这个函数的作用是啥呀,我不是很清楚,y总语法课哪里讲了秦九韶算法呀,我去看看
res = res * r + get(c);这行是秦九韶算法的主要代码逻辑。get(c) 这个函数的作用就是把某位上的字符转换为他所代表的数值大小。像十六进制中的A代表10一样。
我记得y总在语法基础课里讲过两次这个秦九韶算法,但我一时没找到在哪里了,抱歉同学
谢谢兄弟
很有帮助,感谢分享
厉害呀兄弟,真希望我也能像你一样总结出来自己的东西。
好兄弟,你也会的,平时做好笔记和总结!在互联网时代,感觉做个电子笔记比纸质笔记要好一些。方便复习和积累来不断提高自己。
谢谢好兄弟
太棒啦!hxd
总结能力真滴强!
期待后续哦
谢谢同学haha!!!
兄弟🐮🍺!
谢谢同学,hah