本篇用来总结自己的一些学习笔记和心得。
以下主要分为题型注意、代码笔记、公开课笔记三个方面。
一、题型注意
均需注意的细节
①flag等标志变量或通用量的初始化
②确定好数据范围及各变量的含义
- 第一题:单循环+分支语句
细节:long long、边界、特殊情况 - 第二题:多重循环/数据排序(接近n方)
思路:以时间为数组下标、差分、前缀和(一维、二维) - 第三题:工程题,不具备算法难度,具有一定工作量
思路:字典序 - 第四题:具备一定算法难度,如bfs、dfs、最短路径、图
- 第五题:不仅具备算法难度,从题到算法的映射也比较难
二、代码笔记
// 万能头文件
#include<bits/stdc++.h>
// 简写memset函数,其头文件在string.h中
#define mem(f,v) memset(f, v, sizeof(f));
// 看到10^9时,判断是否需要ll类型,提前缩写
// 注意double类型输入用%lf,输出用%f
typedef long long ll;
// 定义范围界限,比要求的大一点
const int maxn = 100010;
// 定义int型变量最大值
const int inf = ~(1u << 31u);
// 定义ll类型变量最大值
const ll linf = ~(1llu << 63u);
// 勿忘使用名字空间
using namespace std;
// 使用枚举类型表示在平面上的移动方向
// 使用dx、dy数组表示移动的x、y变量
enum LighterDir {
X_POS = 0,
Y_POS = 1,
X_NEG = 2,
Y_NEG = 3 // 注意内部之间用, 最后无,
};
int dx[] = { 1, 0, -1, 0 }, dy[] = { 0, 1, 0, -1 };
// 输出的进制转换
// 换行使用“\n”而不是endl,提高速度
int baseChange(int x) {
cout << x << "\n";
cout << std::oct << x << "\n";
cout << std::hex << x << "\n";
cout << std::dec << x << "\n";
}
// map的使用
map<int, map<int, int>>psy;// 以y作为索引
int mapUse(){
// 可以直接用下标赋初始值
psy[1][1] = 1;
// 令auto为大map中以0为key的value
auto it = psy.find(0);
// 如果没找到
if(it == psy.end()){
map<int, int>add;// 新建一个
add.insert({1,1}); // 加入到小map中
psy.insert({1, add}); // 加入到大map中
/********** 注意大括号{} ***********/
}else{
// 找到后直接加入(second是value,此处为小map)
it -> second.insert({1,1});
}
}
// set的使用
struct node {
int x, y;
ll d;
// 构造函数
node(int x, int y, ll d) : x(x), y(y), d(d) {}
//运算符重载,配合set使用,注意两个const
bool operator < (const node &t) const {
//d小的更小,如果相等则x更小的更小
return d == t.d ? x < t.x : d < t.d;
}
};
// set的使用
set <node>q;
int useSet(int n, int a, int b) {
int x, y;
for (int i = 1; i <= n; ++i) {
cin >> x >> y;
// pow(a,b)是a的b次方,abs(a)是a的绝对值
ll dist = pow(abs(x - a), 2) + pow(abs(y - b), 2);
// node构造函数的使用
node fresh(x, y, dist);
// 将新node加入set中
q.emplace(fresh);
// 删除node
q.erase(fresh);
}
// 输出set中排序最前面的(最小的)
cout << q.begin()->d << "\n";
// 删除set中的元素
q.erase(q.begin());
// 函数要有返回值
return 0;
}
// vector的使用
struct info{
int u, v, x;
info(int u, int v, int x) : u(u), v(v), x(x) {}
};
vector<info>dv[maxn];
int vectorUse() {
int x, y, z;
cin >> x >> y >> z;
//使用构造函数初始化node
info fresh(x, y, z);
// 将新node加入到vector中
/********** 不像map,需要先push进去后才能用下标访问 *********/
dv[0].emplace_back(fresh);
// 判空
if(dv[0].begin() == dv->end())return 1;
// vector中第一个元素的访问
int A_part = dv[0].begin()->u + dv[0].begin()->v;
// vector的遍历
for (const auto&x : dv[0]) {
cout << x.u << x.v;
}
for(auto ite = dv[0].begin(); ite != dv[0].end(); ++ite){
cout << ite->u << "\n";
}
// 清空
dv[0].clear();
return 0;
}
// double的判整
int isDoubleInt(double x) {
int y = (int)x;
if (x - y == 0)return 1;
else return 0;
}
// 得到从1到x13的素数个数
int getPrimeNum(int n) {
int sum = 1;// 2单独处理
for (int i = 3; i <= n; i += 2)// 素数不偶,只看奇数
{
int j;
// 如果数字∈[2,i - 1]都无法整除i,则i是素数
for (j = 2; j < i; ++j)
if (i%j == 0)break;
if (j == i)
sum++;
}
return sum;
}
// 判断是否含有7
// bool类型表示对错,避免超时
bool have7(int x) {
// 直到判断完所有的位
while (x) {
// 先看此时的个位是否有7
if (x % 10 == 7) return true;
// 再去掉此时的个位,十位变成了个位
else x /= 10;
}
return false;
}
// 满足输出的精度要求
void outWithPrecise(ll x) {
cout << fixed << setprecision(2) << x << "\n";// c++
printf("%.2f\n", x); // c
// void也要return
return;
}
int main()
{
// 提高sin、cout速度
ios::sync_with_stdio(false);
// 输入重定向,加快输入长数据速度
/********* 提交前注释掉! ********/
freopen("in.txt", "r", stdin);
return 0;
}
三、公开课笔记