C C++最新【蓝桥杯专题】双指针 BFS 图论 (C++ 洛谷 acwing 蓝桥,2024年最新骚年你的屏幕适配方式该升级了

img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取

在这里插入图片描述

链接 链接

  • 思路 : 不断优化 缩减区间 , 具体看代码注释
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>

using namespace std;

const int N = 100010;   //根据题目数据范围,定N大小,此题则主要根据N,ts,id来确定的
typedef pair<int, int> PII; //定义一个PII类型以及一对int整型用于存储ts和id

#define x first //为了代码简洁,则分别把first, second 宏定义为x, y
#define y second
int n, d, k;
int cnt[N]; //用于存储每个id号获得赞数,所以后面代码为cnt[t] ++;
bool st[N]; //用于存储每个帖子是否是热帖,所以用bool类型
PII logs[N];//用于存储日志ts, id

int main()
{
    scanf("%d %d %d", &n, &d, &k);
    for(int i = 0; i < n; i ++) scanf("%d %d\n", &logs[i].first, &logs[i].second);

    sort(logs, logs + n);

    for(int i = 0, j = 0; i < n; i ++)//双指针算法,i在前,j在后
    {
        int t = logs[i].second;//把每个获赞的帖子id存入t
        cnt[t] ++;//获得一个赞,所以此刻 ++;
        while(logs[i].first - logs[j].first >= d)//如果俩个帖子时间相差超过d,说明该赞无效
        {
            cnt[logs[j].second] --;//所以此刻--;
            j ++;//要把指针j往后,否则死循环
        }
        if(cnt[t] >= k) st[t] = true; //如果该id贴赞超过k,说明是热帖
    }
    for(int i = 0; i < 100000; i ++)
    {
        if(st[i])//如果为真,则把热帖的id打印出来
            cout << i << endl;
    }

    return 0;
}



bfs献给阿尔吉侬的花束 (BFS 模板t)

BFS 通常用于求解——》 最短路径
链接 链接


#include <iostream>
#include <queue>
#include <cstring>
using namespace std;
typedef pair<int, int> PII;

const int N = 210;

char a[N][N];
int dis[N][N];

void bfs(PII start) {
    queue<PII> q;
    q.push(start);//队头队,对应步骤1
    while(!q.empty()) {
        PII u = q.front();
        q.pop();
        int dx[4] = {-1, 0, 1, 0};
        int dy[4] = {0, 1, 0 ,-1};
        for(int i = 0; i < 4; i++) {//遍历四个方向,对应步骤2
            int x = u.first + dx[i];
            int y = u.second + dy[i];
            if(a[x][y] == '#') continue;//如果是'#',不做任何处理
            if(a[x][y] == '.') {//如果是 '.',更新对应内容
                dis[x][y] = dis[u.first][u.second] + 1;
                a[x][y] = '#';
                q.push({x, y});
            }
            if(a[x][y] == 'E') {//如果是'E',找到了,输出
                cout << dis[u.first][u.second] + 1 << endl;
                return;
            }
        }
    }
    cout << "oop!" << endl;//没有找到
}

int main() {
    int t;
    cin >> t;
    while(t--) {
        memset(a, '#', sizeof(a));//初始化地图,各个点都是墙。
        memset(dis, 0, sizeof(dis));//初始化dis
        int n,m;
        PII start;
        cin >> n >> m;
        for(int i = 1; i <= n; i++)  {//从第一行存储地图,因为四周都是墙,bfs时,可以不做越界判断
            for(int j = 1; j <= m; j++)  {//从第一;列存储地图,因为四周都是墙,bfs时,可以不做越界判断
                cin >> a[i][j];
                if(a[i][j] == 'S')//记录下起点位置。
                start.first = i, start.second = j, a[i][j] = '#';
            }
        }
        bfs(start);
    }
    return 0;
}


1113. 红与黑 (BFS)

#include<iostream>
#include<cstring>
#include<cstdio>
#include <limits.h>
#include<algorithm>
#include <string>
#include <vector>
#include <queue>
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,  int> PII;
#define rep(i, a, n) for(int i = a; i <= n; i ++)
#define per(i, a, n) for(int i = n; i <= a; i --)
#define pb push\_back
#include <stdlib.h> // atoi
#define debug cout<<"debug"<<"\n"
#define endl "\n";
const int INF = 0x3f3f3f3f;
const int mod=1e9+7;
const int N  = 30;
#define x first
#define y second


char g[N][N];
int cnt[N][N];

int dx[4] = {0, 1, 0, -1};
int dy[4] = {1, 0, -1, 0};

int bfs (PII s) {
    int res = 1;
    queue<PII> q;
    q.push(s);
    while(!q.empty()) {
        auto t = q.front();
        q.pop();
        for(int i = 0; i < 4; i ++) {
            int xx = dx[i] + t.x , yy = dy[i] + t.y;
            if(g[xx][yy] == '#') continue;
            if(g[xx][yy] == '.') {
                // cnt[xx][yy] = cnt[t.x][t.y] + 1;
                g[xx][yy] = '#';
                q.push({xx, yy});
                res ++ ;
            }
        }
    }
    return res;
}

void solve () {
    int n, m;
    while(cin >> n >> m) {
        if(n == 0 && m == 0) break;
        memset(g, '#', sizeof g);
        // memset(cnt , 0, sizeof cnt);
        PII s;
        rep(i , 1, m) {
            rep(j , 1, n) {
                cin >> g[i][j];
                if(g[i][j] == '@') {
                    s.x = i;
                    s.y = j;
                    g[i][j] = '#';
                }
            }
        }
        cout << bfs(s) <<endl;
    }

}

int main(void){
    ios::sync\_with\_stdio(false);cin.tie(0);cout.tie(0);
	int T = 1;
    // cin >> T;
	while(T --) solve();
	return 0;
}


完全二叉树的权重 【双指针 O(nlogn)】

链接 链接
一个数据结构题 : 完全二叉树的最右边的节点为 2 * i - 1 最左的节点为 2depth

#include<iostream>
#include<cstring>
#include<cstdio>
#include <limits.h>
#include<algorithm>
#include <string>
#include <vector>
#include <queue>
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,  int> PII;
#define rep(i, a, n) for(int i = a; i <= n; i ++)
#define per(i, a, n) for(int i = n; i <= a; i --)
#define pb push\_back
#include <stdlib.h> // atoi
#define debug cout<<"debug"<<"\n"
#define endl "\n"
const int INF = 0x3f3f3f3f;
const int mod=1e9+7;
const int N  = 30;
#define x first
#define y second

int a[N];
int cnt[N];

ll minn = INF;
ll maxx = -INF;

void solve () {
    int n;
    rep(i , 1 , n) cin >> a[i];
    
    int depth = 0;
    for(int d = 1, i = 1; i <= n; i \*= 2, d ++) {
        ll s = 0;
        for(int j = i; j < i + (1 << d - 1) && j <= n; j ++) {
            s += a[i];
        }
        if(s > maxx) {
            maxx = s;
            depth = d;
        }
    }
    cout << depth << endl;
    // for(int i = 1; i < n ; i+)
}

int main(void){
// freopen("in.txt","r",stdin);
    ios::sync\_with\_stdio(false);cin.tie(0);cout.tie(0);
	int T = 1;
    // cin >> T;
	while(T --) solve();
	return 0;
}


地牢大师

链接 链接
思路 : 三维坐标, 用结构体存储 , queue 用不了 可以模拟队列 hh 头指针 tt 尾指针 https://www.acwing.com/video/257/

在这里插入图片描述

**判断 越界就 continue
能走 就 dis + 1

左孩子右兄弟

题目链接
左孩子右兄弟表示法是一种将树转化成一颗二叉树的方法;
该方法将某节点的所有兄弟节点都定位该节点的右孩子, 将该节点的任意一个孩子定位左孩子;
题目要求能够造出二叉树的最大深度;

经过观察可得, 某一层节点能够形成的深度其实就是该节点的兄弟的数量;
因此要使树的深度最深, 则树的向下构造节点的孩子数量要尽量多;
状态表示f[i] : 表示i节点作为根节点能够形成二叉树的高度;
对哪一个节点向下构造做分类: f[i] = max(f[j]) + cnt;(cnt为i节点的孩子数量)
初始化:无;
答案: f[1];



#include <cstring>
#include <iostream>
#include <algorithm>
const int N =  1e5 + 10;
using namespace std;

int n;
int h[N], ne[N], e[N], idx = 0;
int f[N];

void add(int a, int b){
    e[idx] = b, ne[idx] = h[a], h[a] = idx ++;
}

void dfs(int x) {
    int cnt = 0;
    for(int i = h[x]; i != -1; i = ne[i]) {
        int j = e[i];
        dfs(j);
        cnt ++;
        f[x] = max(f[x], f[j]);
    }
    f[x] += cnt;
}

void solve () {
    cin >> n;
    memset(h, -1 , sizeof h);
    for(int i = 2; i <= n; i ++) {
        int v;
        cin >> v;
        add(v, i);
    }
    dfs(1);
    cout << f[1] << endl;
}

int main(void){
	// freopen("in.txt","r",stdin);
    ios::sync\_with\_stdio(false);cin.tie(0);cout.tie(0);
	int T = 1;
    // cin >> T;
	while(T --) solve();
	return 0;
}


国际象棋

题目链接

#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,  int> PII;
#define rep(i, a, n) for(int i = a; i <= n; i ++)
#define per(i, a, n) for(int i = n; i <= a; i --)
#define pb push\_back
#include <stdlib.h> // atoi
#define debug cout<<"debug"<<"\n"
#define endl "\n"
const int INF = 0x3f3f3f3f;
const int mod=1e9+7;
const int N  = 110;
const int M = N \* 2;
#define x first
#define y second

int dx[8] = {-2, -1, 1, 2, 2, 1, -1, -2};
int dy[8] = {1, 2, 2, 1, -1, -2, -2, -1};
int cnt [N][N];

int res = 0;
int n, m , k;

void dfs(int x, int y, int sum) {
    if(sum == k) {
        res = (res + 1) % mod;
        return ;
    }
    if(y > m) {
        y = 1, x ++;
        if(x > n) return ;
    }

    dfs(x, y + 1, sum); // 不放马

    if(!cnt[x][y]) {
        cnt[x][y] ++;
        for(int i = 0; i < 8; i ++) {
            int a = x + dx[i], b = y + dy[i];
            if(a < 1 || a > n || b < 1 || b > m) continue;
            cnt[a][b]++;
        }
        dfs(x, y + 1, sum);
        cnt[x][y] --;
        for(int i = 0; i < 8; i ++) {
            int a = x + dx[i], b = y + dy[i];
            if(a < 1 || a > n || b < 1 || b > m) continue;
            cnt[a][b] --;
        }
        // cnt[x][y] --;
    }

}

void solve () {
    cin >> n >> m >> k;
    dfs(1, 1, 0);
    cout << res  << endl;
}


![img](https://img-blog.csdnimg.cn/img_convert/6fa48b98a5b7432130987b7b9bf7ce19.png)
![img](https://img-blog.csdnimg.cn/img_convert/14ae7e02471ec17f7c0f4fd41f1f37dc.png)

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!**

**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**

**[如果你需要这些资料,可以戳这里获取](https://bbs.csdn.net/topics/618668825)**

ue;
            cnt[a][b] --;
        }
        // cnt[x][y] --;
    }

}

void solve () {
    cin >> n >> m >> k;
    dfs(1, 1, 0);
    cout << res  << endl;
}


[外链图片转存中...(img-o81S5oZb-1715726712925)]
[外链图片转存中...(img-GlMvBz1C-1715726712926)]

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!**

**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**

**[如果你需要这些资料,可以戳这里获取](https://bbs.csdn.net/topics/618668825)**

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值