双指针,BFS和图论

📟作者主页:慢热的陕西人

🌴专栏链接:力扣刷题日记

📣欢迎各位大佬👍点赞🔥关注🚓收藏,🍉留言

文章目录

双指针,BFS和图论

1.日志系统

链接:1238. 日志统计 - AcWing题库

思路:我们先将所有的数据读入然后按照时间顺序进行排列存储在一个pair数组内部,然后一次去遍历时间区间

[j, i]为时间跨度,我们每次都是将一个长度为小于d的时间区间向前移动,那么我们每次只需要加上新增的日志,并且减去最左边被移除区间的日志,即可快速的计算区间内的日志的点赞数量。

cpp 复制代码
#include<cstdio>
#include<iostream>
#include<utility>
#include<algorithm>

using namespace std;

#define x first
#define y second

typedef pair<int, int> PII;

const int N = 100010;

PII tid[N];

int cnt[N], st[N];

int n,d,k;


int main()
{
    cin >> n >> d >> k;
    for(int i = 0; i < n; ++i) scanf("%d%d", &tid[i].x, &tid[i].y);
    
    //对时间排序
    sort(tid, tid + n);
    
    for(int i = 0, j = 0; i < n; ++i)
    {
        cnt[tid[i].y]++;
        while(tid[i].x - tid[j].x >= d)
        {
            cnt[tid[j].y]--;
            j++;
        }
        if(cnt[tid[i].y] >= k) st[tid[i].y] = true;
    }
    for(int i = 0; i < 100000; ++i)
        if(st[i]) cout << i << endl;
    
    return 0;
}

2.献给阿尔吉农的花束

链接:1101. 献给阿尔吉侬的花束 - AcWing题库

思路:广度优先遍历,一个二位数组用于存放当前点的最短距离。

cpp 复制代码
#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>

using namespace std;

#define x first
#define y second

typedef pair<int, int> PII;

int m, n;

const int N = 210;

char g[N][N];
int dist[N][N];

int bfs(PII start, PII end)
{
    queue<PII> q;
    memset(dist, -1, sizeof dist);

    dist[start.x][start.y] = 0;

    q.push(start);

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

    while (!q.empty())
    {
        PII t = q.front();

        q.pop();

        for (int i = 0; i < 4; ++i)
        {
            int a = t.x + dx[i], b = t.y + dy[i];

            if (a >= 0 && a < m && b >= 0 && b < n && g[a][b] != '#' && dist[a][b] == -1)
            {
                dist[a][b] = dist[t.x][t.y] + 1;

                if (end == make_pair(a, b))
                    return dist[a][b];

                q.push({a, b});
            }
        }
    }
    return -1;
}

int main()
{
    int t;
    PII start, end;
    cin >> t;
    while (t--)
    {
        scanf("%d%d", &m, &n);
        for (int i = 0; i < m; ++i)
        {
            for (int j = 0; j < n; ++j)
            {
                cin >> g[i][j];
                if (g[i][j] == 'S')
                    start = {i, j};
                else if (g[i][j] == 'E')
                    end = {i, j};
            }
        }

        int ret = bfs(start, end);
        if (ret == -1)
            cout << "oop!" << endl;
        else
            cout << ret << endl;
    }

    return 0;
}

3.交换瓶子

链接:1224. 交换瓶子 - AcWing题库

思路:图论的思想,我们将原序列从下标1开始,放入到数组中,这时候我们可以建立起一个序列中元素和数组下标的映射,那么我们会发现会产生若干个环:

并且我们发现,当我们将同一个环内的点进行交换,那么我们就可以得到两个环。

我们将不同环内的点进行交换,那么我们可以将两个环合并为一个环。

所以我们的目标就变成将原来的k个环变成n个环,那么我们需要分别n - k即可;

cpp 复制代码
#include<iostream>

using namespace std;

const int N = 10010;

int g[N];
bool st[N];


int main()
{
    int n, cnt = 0;
    cin >> n;
    
    for(int i = 1; i <= n; ++i) cin >> g[i];
    
    for(int i = 1; i <= n; ++i)
        if(!st[i])
        {
            cnt++;
            for(int j = i; !st[j]; j = g[j])
                st[j] = true;
        }
    cout << n - cnt;
    return 0;
}
相关推荐
C语言魔术师12 分钟前
【小游戏篇】三子棋游戏
前端·算法·游戏
自由自在的小Bird12 分钟前
简单排序算法
数据结构·算法·排序算法
王老师青少年编程6 小时前
gesp(C++五级)(14)洛谷:B4071:[GESP202412 五级] 武器强化
开发语言·c++·算法·gesp·csp·信奥赛
DogDaoDao6 小时前
leetcode 面试经典 150 题:有效的括号
c++·算法·leetcode·面试··stack·有效的括号
Coovally AI模型快速验证7 小时前
MMYOLO:打破单一模式限制,多模态目标检测的革命性突破!
人工智能·算法·yolo·目标检测·机器学习·计算机视觉·目标跟踪
可为测控8 小时前
图像处理基础(4):高斯滤波器详解
人工智能·算法·计算机视觉
Milk夜雨8 小时前
头歌实训作业 算法设计与分析-贪心算法(第3关:活动安排问题)
算法·贪心算法
BoBoo文睡不醒9 小时前
动态规划(DP)(细致讲解+例题分析)
算法·动态规划
apz_end9 小时前
埃氏算法C++实现: 快速输出质数( 素数 )
开发语言·c++·算法·埃氏算法
仟濹10 小时前
【贪心算法】洛谷P1106 - 删数问题
c语言·c++·算法·贪心算法