文章目录
输入输出
不用float用double,因为float精度没有double高
scanf("%d",&x); //int型变量
scanf("%lf",&x);//double型变量
scanf("%c",&x); //char型变量
scanf("%s",s); //字符串数组
scanf和gets
1.输入一行字符串带空格的话,使用gets,因为scanf遇到空格会自动结束
2.读入单个字符和输出单个字符,一般在scanf和gets中间使用getchar用于消除回车’\n’的影响
进制转换
int a = 10;
printf("%x\n", a);//小写十六进制输出 答案a
printf("%X\n", a);//大写十六进制输出 答案A
printf("%o\n", a);//八进制输出 答案12
输出增加前置0
int a = 5;
printf("%02d\n", a);//其中2代表宽度 不足的地方用0补充
%g
有小数输出小数,没小数输出整数
long long的使用
很多情况下的计算会超出int,比如求N!,N比较大的时候int就存不下了,这时候我们就要用long long 。int范围-1e9到1e9,long long范围-1e18到1e18
long long x;
scanf("%lld", &x);
printf("%lld\n", x);
字符的ASCII码
如果遇到需要ASCII码的题目的时候记住char字符和int值是可以相互转化的。
printf("%d\n", 'a');//输出结果97
printf("%d\n", 'A');//输出结果65
cin 和 cout
学会C和C++语法混合使用
当输入或输出格式有特殊要求的时候,cin和cout不方便解决,那么我们还是使用scanf和printf来解决问题。注意printf尽量不要和cout同时使用,会发生不可控制的意外。
头文件技巧
万能头文件
#include <bits/stdc++.h>
using namespace std;
完整头文件
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <time.h>
#include <algorithm>
#include <iostream>
#include <queue>
#include <stack>
#include <vector>
#include <string>
using namespace std;
int main() {
return 0;
}
数组使用
作为标记
f[i]的值表示i这个数有多少个,初始的时候每个值的个数都是0。
存储地图
数组的使用不一定从0开始,可以从任意下标开始,只要我们使用的时候对应上就行。
char mpt[10][10];
for (int i = 1; i <= 4; i++) {
scanf("%s", mpt[i] + 1);
/* 不要用下面这种输入方式,否则会出问题,因为回车也算一个char字符
for (int j = 1; j <= 4; j++) {
scanf("%c", &mpt[i][j]);
}
*/
}
数组嵌套
p[f[i]] = i;
审时度势
时间复杂度
时限1s
O(N) ~ N最大在500W左右
O(NlogN) ~ N最大在20W左右
O(N^2) ~ N最大在2000左右
O(N^2logN) ~ N最大700在左右
O(N^3) ~ N最大在200左右
O(N^4) ~ N最大在50左右
O(2^N) ~ N最大在24左右
O(N!) ~ N最大在10左右
空间复杂度
空间复杂度一般不会限制,如果遇到了再想办法优化空间。
int[3000][3000]
C++STL的使用
排序
sort()函数:依次传入三个参数,要排序区间的起点,要排序区间的终点+1,比较函数。比较函数可以不填,则默认为从小到大排序(升序)。
升序:sort(begin,end,less<data-type>());
降序:sort(begin,end,greater<data-type>()).
#include <bits/stdc++.h>
using namespace std;
int a[105];
int main() {
int n;
scanf("%d", &n);
for (int i = 0; i < n; i++) {
scanf("%d", &a[i]);
}
sort(a, a+n);
for (int i = 0; i < n; i++)
printf("%d ", a[i]);
return 0;
}
查找
在从小到大的排序数组中
lower_bound( begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于或等于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
upper_bound( begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
在从大到小的排序数组中,重载lower_bound()和upper_bound()
lower_bound( begin,end,num,greater<type>() ):从数组的begin位置到end-1位置二分查找第一个小于或等于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
upper_bound( begin,end,num,greater<type>() ):从数组的begin位置到end-1位置二分查找第一个小于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
#include<bits/stdc++.h>
using namespace std;
int cmp(int a,int b){
return a>b;
}
int main(){
int num[6]={1,2,4,7,15,34};
sort(num,num+6); //按从小到大排序
int pos1=lower_bound(num,num+6,7)-num;
//返回数组中第一个大于或等于被查数的值
int pos2=upper_bound(num,num+6,7)-num;
//返回数组中第一个大于被查数的值
cout<<pos1<<" "<<num[pos1]<<endl;
cout<<pos2<<" "<<num[pos2]<<endl;
sort(num,num+6,cmp); //按从大到小排序
int pos3=lower_bound(num,num+6,7,greater<int>())-num;
//返回数组中第一个小于或等于被查数的值
int pos4=upper_bound(num,num+6,7,greater<int>())-num;
//返回数组中第一个小于被查数的值
cout<<pos3<<" "<<num[pos3]<<endl;
cout<<pos4<<" "<<num[pos4]<<endl;
return 0;
}
优先队列
通过priority_queue<int> q 来定义一个储存整数的空的priority_queue。
当然priority_queue可以存任何类型的数据,比如priority_queue<string> q等等。
#include <iostream>
#include <queue>
using namespace std;
int main() {
priority_queue<int> q;//定义一个优先队列
q.push(1);//入队
q.push(2);
q.push(3);
while (!q.empty()) {//判读队列不为空
cout << q.top() << endl;//队首元素
q.pop();//出队
}
return 0;
}
vector
用数组存不下时
通过vector<int> v来定义一个储存整数的空的vector。
当然vector可以存任何类型的数据,比如vector<string> v等等。
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<int> v;//定义一个空的vector
for (int i = 1; i <= 10; ++i) {
v.push_back(i * i); //加入到vector中
}
for (int i = 0; i < v.size(); ++i) {
cout << v[i] << " "; //访问vecotr的元素
}
cout << endl;
return 0;
}
queue
先进先出,用于深搜或广搜
通过queue<int> q来定义一个储存整数的空的queue。
当然queue可以存任何类型的数据,比如queue<string> q等等。
#include <iostream>
#include <queue>
using namespace std;
int main() {
queue<int> q;//定义一个队列
q.push(1);//入队
q.push(2);
q.push(3);
while (!q.empty()) {//当队列不为空
cout << q.front() << endl;//取出队首元素
q.pop();//出队
}
return 0;
}
stack
先进后出,浏览器
通过stack<int> S来定义一个全局栈来储存整数的空的stack。
当然stack可以存任何类型的数据,比如stack<string> S等等。
#include <iostream>
#include <stack>
using namespace std;
stack<int> S;//定义一个栈
int main() {
S.push(1);//入栈
S.push(10);
S.push(7);
while (!S.empty()) {//当栈不为空
cout << S.top() << endl;//输出栈顶元素
S.pop();//出栈
}
return 0;
}
map
查找类问题,内部为红黑树,log
通过map<string, int> dict来定义一个key:value映射关系的空的map。
当然map可以存任何类型的数据,比如map<int, int> m等等。
#include <iostream>
#include <string>
#include <map>
using namespace std;
int main() {
map<string, int> dict;//定义一个map
dict["Tom"] = 1;//定义映射关系
dict["Jone"] = 2;
dict["Mary"] = 1;
if (dict.count("Mary")) {//查找map
cout << "Mary is in class " << dict["Mary"];
}
//使用迭代器遍历map的key和value
for (map<string, int>::iterator it = dict.begin(); it != dict.end(); ++it) {
cout << it->first << " is in class " << it->second << endl;
}
dict.clear();//清空map
return 0;
}
set
去除相同的数据
通过set<string> country来定义一个储存字符串的空的set。
当然set可以存任何类型的数据,比如set<int> s等等。
#include <iostream>
#include <set>
using namespace std;
int main() {
set<string> country;//定义一个存放string的集合
country.insert("China");//插入操作
country.insert("America");
country.insert("France");
set<string>::iterator it;
//使用迭代器遍历集合元素
for (it = country.begin(); it != country.end(); ++it) {
cout << * it << " ";
}
cout << endl;
country.erase("American");//删除集合内的元素
country.erase("England");
if (country.count("China")) {//统计元素个数
cout << "China in country." << endl;
}
country.clear();//清空集合
return 0;
}
多组输入
C语言
#include <bits/stdc++.h>
using namespace std;
int main() {
int a, b;
/*或者
while (~scanf("%d%d", &a, &b)) {
printf("%d\n", a+b);
}
*/
while (scanf("%d%d", &a, &b) != EOF) {
printf("%d\n", a+b);
}
return 0;
}
C++
#include <bits/stdc++.h>
using namespace std;
int main() {
int a, b;
while (cin >> a >> b) {
cout << a + b << endl;
}
return 0;
}
Java
Scanner stdin = new Scanner(System.in);
while (stdin.hasNext()) {
String s = stdin.next();
int n = stdin.nextInt();
double b = stdin.nextDouble();
}
Python
while True:
try:
a, b = map(int, input().split())
c = a+b
print(c)
except: #读到文件末尾抛出异常结束循环
break