C++ 竞赛学习路线笔记

C++ 竞赛学习路线笔记

一、基础运算与输入输出

1. 基础公式

  • 求和:sum = 0

  • 求乘积:sum = 1

  • 交换两个数:swap(a, b)

  • 输入整数:cin >> a

  • 输出整数:printf("%d", a);

2. 判断条件

  • n 能被 i 整除:n % i == 0

  • 偶数:n % 2 == 0

  • 奇数:n % 2 == 1

3. 最值查找

  • 最大值:max = -99999if(max < ?) max = ?

  • 最小值:min = 999999if(min > ?) min = ?

4. 循环控制

  • 统计数量:cnt = 0; cnt++;

  • 循环 1~n:for(int i=1; i<=n; i++){}

  • 输入 n 个数:for(int i=1; i<=n; i++){ cin >> x; }

  • 中断循环:break

  • 跳过本轮:continue

  • 输入若干数:while(cin >> n){}


二、数组

1. 一维数组

  • 输入 n 个值:for(int i=1; i<=n; i++) cin >> a[i];

  • 倒序输出:for(int i=n-1; i>=0; i--)

2. 二维数组(n*m 矩阵)

cpp 复制代码
for(int i=1; i<=n; i++){
    for(int j=1; j<=m; j++){
        cin >> a[i][j];
    }
}
  • 主对角线:i == j

  • 副对角线:i + j == n + 1

3. 字符数组 / 字符串

  • 字符数组长度:#include <cstring>strlen(数组名)

  • 字符串长度:#include <string>变量名.size()

  • 整行读取:getline(cin, 变量名)

  • 截取子串:s.substr(起始位置, 长度)

  • 查找字符:s.find(字符),未找到返回 string::npos

  • 替换内容:s.replace(起始位置, 长度, 新字符串)

  • 删除字符:s.erase(起始位置, 长度)

  • 插入字符:s.insert(位置, 字符串)

  • 转整数:stoi(s)stoll(s)(long long)

  • 整数转字符串:to_string(数字)


三、排序与库函数

1. 排序

  • 升序:sort(数组名, 数组名+长度);#include <algorithm>

  • 降序:sort(数组名, 数组名+长度, greater<int>());

2. 数学函数(#include <cmath>

  • 幂:pow(2, 10)

  • int 绝对值:abs(-5)

  • float 绝对值:fabs(-5.999)

  • 平方根:sqrt(225)

  • 最大/最小:max(25, 6)min(25, 6)

  • 向下取整:floor(5.9)

  • 向上取整:ceil(5.2)

  • 两点距离:sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1))


四、STL 容器(#include <bits/stdc++.h>

1. vector 动态数组

  • 定义:vector<int> v;
  • 尾部添加:v.push_back(值);
  • 尾部删除:v.pop_back();
  • 访问元素:v[i]v.at(i)
  • 获取大小:v.size()
  • 清空数组:v.clear()
  • 判空:v.empty()
  • 排序:sort(v.begin(), v.end());

2. map 映射(键值对)

  • 定义:map<string, int> mp;
  • 插入/修改:mp["key"] = value;
  • 访问:mp["key"]
  • 查找键:mp.count("key")(返回0或1)
  • 遍历:
cpp 复制代码
for(auto &p : mp){
    cout << p.first << " " << p.second << endl;
}

3. set 集合(自动去重+排序)

  • 定义:set<int> s;
  • 插入:s.insert(值);
  • 删除:s.erase(值);
  • 查找:s.count(值)(返回0或1)
  • 获取大小:s.size()

4. pair 二元组

  • 定义:pair<int, int> p = {1, 2};
  • 访问:p.first, p.second
  • 比较:先比first,再比second

五、函数

1. 函数模板

cpp 复制代码
函数类型 函数名(参数1, 参数2...){
    return ?;
}

2. 质数判断

cpp 复制代码
bool isprime(int n){
    for(int i=2; i*i<=n; i++){
        if(n%i==0) return false;
    }
    return true;
}

3. 因子和

cpp 复制代码
int yinzi(int n){
    int sum=0;
    for(int i=1; i<n; i++){
        if(n%i==0) sum += i;
    }
    return sum;
}

4. 斐波那契递推式

f[i] = f[i-1] + f[i-2]; (i>=3)

5. 最大公约数 gcd

cpp 复制代码
int gcd(int a,int b){
    if(b==0) return a;
    return gcd(b,a%b);
}

五、位运算

  • 与:&

  • 或:|

  • 异或:^

  • 左移:<<

  • 右移:>>


六、常用算法缩写与工具

  • dfs:深度搜索

  • binary_search:二分查找

  • vis:标记数组

  • hanoi:汉诺塔

  • mergesort:归并排序

  • quicksort:快速排序

  • bubblesort:冒泡排序

  • dp:动态规划

  • sizeof:字节数

  • memset:初始化

  • INF:无穷大

  • lower_bound:下限

  • upper_bound:上限

  • even:偶数

  • odd:奇数


七、数据结构

1. 链表 vs 顺序表

  • 链表:可插删、不可随机访问

  • 顺序表(数组):可随机访问

2. 栈 stack(先进后出)

  • push(值)

  • pop()

  • top()

  • size()

  • empty()

3. 队列 queue(先进先出)

  • push()

  • pop()

  • front()

  • back()

4. 二叉树

  • 节点 i:左孩子 2*i,右孩子 2*i+1

  • 先序:根左右

  • 中序:左根右

  • 后序:左右根


八、算法思想

1. 递推

  1. 初始化

  2. 循环写递推公式

2. 递归

  1. 边界结束

  2. 自身调用

3. 贪心

  1. 结构体/数组

  2. 输入

  3. sort 排序

  4. 循环操作

4. 分治

快速排序、归并排序、二分查找

5. 二分查找模板

cpp 复制代码
while(l<=r){
    int mid = (l+r)/2;
    if(a[mid]<x) l=mid+1;
    else r=mid-1;
}

6. 动态规划 DP

  1. 输入

  2. 初始化状态

  3. 状态转移方程

  4. 输出结果

7. DFS 模板

cpp 复制代码
void dfs(int t){
    for(int i=1;i<=运算种数;i++){
        if(满足条件){
            保存结果/标记;
            if(到达目的地){
                输出结果;
            }else{
                dfs(t+1);
            }
            回溯/清空标记;
        }
    }
}

8. BFS 模板

cpp 复制代码
void bfs(){
    初始值入队;
    标记已用;
    while(队列不空){
        for(四种方向){
            新坐标=队头+方向;
            if(越界) continue;
            if(合法且未占用){
                入队;
                标记占有;
            }
            if(到达终点) 输出;
        }
        出队;
    }
}

九、时间复杂度

  • O(n²):冒泡、插入、选择

  • O(n):桶排序

  • O(n log n):快速排序、归并排序


十、计算机基础

  • 1 Byte = 8 bit

  • 1 MB = 1024 KB = 1024*1024 B

  • 十进制转 X 进制:短除法,倒取余数

  • CPU:运算器 + 控制器 + 寄存器


十二、高精度运算(大整数)

1. 高精度加法

cpp 复制代码
高精度的加法思想
	1.把大数存到字符串; 
	2.字符串的每个字符数字都通过ASCII转换存到数组,
	注意的是要低位存在数组开头:a[i] = s[len-i-1]-'0';
	
	3.获取最大的数长度:max(len1,len2) ;
	4.把a,b值加入到c数组: c[i] = a[i]+b[i]; 
	
	5.c数组加法进位的算式:
	①	c[i+1] += c[i]/10; 
	②  c[i] %= 10;
	
	6.数字溢出,长度+1;
	7.反向输出结果;

2. 高精度减法(a >= b)

cpp 复制代码
高精度减法的思想
	1.输入大数; 
	2.判断大小,固定s1恒大于s2:
	if(s1.size()<s2.size() || s1.size()==s2.size() && s1<s2){
		swap(s1,s2); //交换值
		cout<<"-";
	} 
	3.获取长度;
	4.字符变整数:a[i] = s1[len1-i-1]-'0';
	5.减法运算:
		if(a[i]<b[i]){
			a[i+1]--; //上位-- 
			a[i]+=10; // 本位+10 
		}
		c[i] = a[i]-b[i]; 

	6.去除前导零;
	while(c[len1-1]==0 && len1>1){
		len1--;
	} 
	7.反向输出;

3. 高精度乘法(大整数 × 小整数)

cpp 复制代码
高精度的乘法思想
	1.把大数存到字符串; 
	2.字符串的每个字符数字都通过ASCII转换存到数组,
	注意的是要低位存在数组开头:a[i] = s1[len-i-1]-'0';
	3.获取长度: len = len1+len2-1; 
	4.乘法进位的算式:
	①	c[i+j] += a[i]*b[j];
	5.c数组的值要进位:
	①	c[i+1] += c[i]/10; 
	②	c[i] %=10; 
	5.数字溢出,长度+1;
		while(c[len]){ 
		c[len+1] +=c[len]/10;
		c[len] %= 10;
		len++;
	}
	6.反向输出结果;

十三、经典例题代码(原样保留)

1. 递推:斐波那契

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
int a[1000005], n, x;
int main(){
    cin>>n;
    a[1]=1;
    a[2]=1;
    for(int i=3;i<=1000000;i++)
        a[i]=(a[i-1]+a[i-2])%1000;
    for(int i=1;i<=n;i++){
        cin>>x;
        cout<<a[x]<<endl;
    }
    return 0;
}

2. 递归:斐波那契

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
long long fbi(int n){
    if(n==1||n==2)
        return 1;
    else return fbi(n-1)+fbi(n-2);
}
int main(){
    int n,x;
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>x;
        cout<<fbi(x)<<endl;
    }
    return 0;
}

3. 贪心:活动选择

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
struct active{
    int b,e;
}a[1005];
int n,cnt=1;
bool cmp(active x,active y){
    if(x.e!=y.e) return x.e<y.e;
    else return x.b<y.b;
}
int main(){
    cin>>n;
    for(int i=1;i<=n;i++)
        cin>>a[i].b>>a[i].e;
    sort(a+1,a+n+1,cmp);
    int first=a[1].e;
    for(int i=2;i<=n;i++){
        if(first<=a[i].b){
            cnt++;
            first=a[i].e;
        }
    }
    cout<<cnt;
    return 0;
}

4. DP:数字金字塔

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
int a[1005][1005],sum[1005][1005];
int n, max1;
int main(){
    cin>>n;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=i;j++){
            cin>>a[i][j];
        }
    }
    sum[1][1]=a[1][1];
    for(int i=2;i<=n;i++)
        for(int j=1;j<=i;j++)
            sum[i][j]=max(sum[i-1][j],sum[i-1][j-1])+a[i][j];
    for(int i=1;i<=n;i++){
        max1=max(max1,sum[n][i]);
    }
    cout<<max1<<endl;
    return 0;
}

5. DFS:组合输出

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
int n,r,a[1000],cnt;
bool f[1000];
void print(){
    for(int i=1;i<=r;i++){
        cout<<a[i]<<" ";
    }
    cout<<endl;
}
void dfs(int t){
    for(int i=1;i<=n;i++){
        if(a[t-1]<i&&f[i]==0){
            a[t]=i;
            f[i]=1;
            if(t==r){
                print();
            }
            else dfs(t+1);
            f[i]=0;
        }
    }
}
int main(){
    cin>>n>>r;
    dfs(1);
    return 0;
}

6. BFS:细胞

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
char a[1005][1005];
int dx[4]={1,-1,0,0};
int dy[4]={0,0,-1,1};
int n,m,cnt;
queue<int>q1,q2;
void bfs(int x,int y){
    q1.push(x);q2.push(y);
    a[x][y]='0';
    while(!q1.empty()){
        for(int i=0;i<4;i++){
            int tx=q1.front()+dx[i];
            int ty=q2.front()+dy[i];
            if(tx<1||ty<1||tx>n||ty>m){
                continue;
            }
            if(a[tx][ty]=='1'){
                q1.push(tx);q2.push(ty);
                a[tx][ty]='0';
            }
        }
        q1.pop();q2.pop();
    }
}
int main(){
    cin>>n>>m;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            cin>>a[i][j];
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            if(a[i][j]=='1'){
                cnt++;
                bfs(i,j);
            }
        }
    }
    cout<<cnt;
    return 0;
}
相关推荐
ShineWinsu2 小时前
对于Linux:文件操作以及文件IO的解析
linux·c++·面试·笔试·io·shell·文件操作
十五年专注C++开发2 小时前
Oat++: 一个轻量级、高性能、零依赖的 C++ Web 框架
开发语言·c++·web服务·oatpp
sensen_kiss2 小时前
CAN302 Technologies for E-Commerce 电子商务技术 Pt.6 市场营销与SEO(搜索引擎优化)
android·学习·搜索引擎
我的xiaodoujiao2 小时前
API 接口自动化测试详细图文教程学习系列9--Requests模块
python·学习·测试工具·pytest
乐园游梦记2 小时前
机器学习:监督学习与无监督学习由浅入深全解析
人工智能·深度学习·学习·机器学习
bobasyu2 小时前
Claude Code 源码笔记 -- queryLoop
java·笔记·spring
woai33642 小时前
JVM学习-基础篇-常见引用
jvm·学习
世人万千丶2 小时前
Flutter 框架跨平台鸿蒙开发 - 家庭健康档案云应用
学习·flutter·华为·开源·harmonyos·鸿蒙
東雪木2 小时前
Java学习——泛型基础:泛型的核心作用、泛型类 / 方法 / 接口的定义
java·学习·java面试