双指针、BFS和图论算法

一、双指针

例题

日志统计

题目信息

在这里插入图片描述
在这里插入图片描述

思路

在这里插入图片描述

题解
#include <bits/stdc++.h>
#define int long long
#define endl '\n'
#define maxsize 100100
using namespace std;

int n,d,k;
int cnt[maxsize];
pair <int,int> num[maxsize];
bool flag[maxsize];

signed main()
{
    ios::sync_with_stdio();
    cin.tie(0);
    cout.tie(0);
    cin>>n>>d>>k;
    for(int i=0;i<n;i++)
    {
        cin>>num[i].first>>num[i].second;
    }
    sort(num,num+n);
    for(int i=0,j=0;j<n;j++)
    {
        cnt[num[j].second]++;
        while(num[j].first-num[i].first>=d)
        {
            cnt[num[i].second]--;
            i++;
        }
        if(cnt[num[j].second]>=k) flag[num[j].second]=true;
    }
    for(int i=0;i<=100000;i++)
    {
        if(flag[i]) cout<<i<<endl;
    }
    return 0;
}

二、BFS

适合用于查找一条合法的路径或最小步数

例题

1、献给阿尔吉侬的花束

题目信息

在这里插入图片描述
在这里插入图片描述

思路

在这里插入图片描述
在这里插入图片描述

题解
#include <bits/stdc++.h>
#define endl '\n'
#define int long long
#define maxsize 210
using namespace std;

int t,r,c;
char maps[maxsize][maxsize];
int dis[maxsize][maxsize];
pair <int,int> weizhi;

int bfs(pair<int,int> start,pair<int,int> end)
{
    queue<pair<int,int>> q;
    memset(dis,-1,sizeof(dis));
    dis[start.first][start.second]=0;
    q.push(start);
    int dx[4]={-1,0,1,0};
    int dy[4]={0,1,0,-1};
    while(!q.empty())
    {
        auto tmp=q.front();
        q.pop();
        for(int i=0;i<4;i++)
        {
            int x=tmp.first+dx[i];
            int y=tmp.second+dy[i];
            //越界的情况
            if(x<0 || y<0 || x>=r || y>=c) continue;
            //障碍物
            if(maps[x][y]=='#') continue;
            //之前已经遍历过
            if(dis[x][y] != -1 ) continue;
            dis[x][y]=dis[tmp.first][tmp.second]+1;
            if(end==make_pair(x,y)) return dis[x][y];
            q.push(make_pair(x,y));
        }
    }
    return -1;
}

signed main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    pair<int,int> start,end;
    cin>>t;
    for(int i=0;i<t;i++)
    {
        cin>>r>>c;
        for(int j=0;j<r;j++)
        {
            for(int k=0;k<c;k++)
            {
                cin>>maps[j][k];
                if(maps[j][k]=='S')
                {
                    start.first=j;
                    start.second=k;
                }
                if(maps[j][k]=='E')
                {
                    end.first=j;
                    end.second=k;
                } 
            }     
        }
        int distance=bfs(start,end);
        if(distance==-1)
        {
            cout<<"oop!"<<endl;
        }
        else{
            cout<<distance<<endl;
        }
    }
    return 0;
}

2、红与黑

题目信息

在这里插入图片描述
在这里插入图片描述

思路

在这里插入图片描述

题解
#include <bits/stdc++.h>
#define int long long
#define maxsize 30
using namespace std;

int h,w;
char maps[maxsize][maxsize];
bool flag[maxsize][maxsize];
queue<pair<int,int>> q;

int bfs(pair<int,int> start)
{
    int count=0;
    int dx[4]={-1,0,1,0};
    int dy[4]={0,1,0,-1};
    q.push(start);
    flag[start.first][start.second]=true;
    count++;
    while(!q.empty())
    {
        auto tmp=q.front();
        q.pop();
        for(int i=0;i<4;i++)
        {
            int x=tmp.first+dx[i];
            int y=tmp.second+dy[i];
            if(x<0 || y<0 || x>=h || y>=w) continue;
            if(maps[x][y]=='#') continue;
            if(flag[x][y]==true) continue;
            q.push(make_pair(x,y));
            flag[x][y]=true;
            count++;
        }
    }
    return count;
}

signed main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    pair<int,int> start;
    while(true)
    {
        cin>>w>>h;
        if(w==0&&h==0) break;
        for(int i=0;i<h;i++)
        {
            for(int j=0;j<w;j++)
            {
                cin>>maps[i][j];
                if(maps[i][j]=='@')
                {
                    start.first=i;
                    start.second=j;
                }
            }
        }
        int cnt=bfs(start);
        cout<<cnt<<endl;
        //恢复现场
        memset(maps,0,sizeof(maps));
        memset(flag,false,sizeof(flag));
    }
    return 0;
}

图论

例题

交换瓶子

题目信息

在这里插入图片描述
在这里插入图片描述

思路

在这里插入图片描述

题解
#include <bits/stdc++.h>
#define endl '\n'
#define int long long
#define maxsize 10010
using namespace std;

int n;
int a[maxsize];
bool num[maxsize];

signed main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    cin>>n;
    int cnt=0;
    for(int i=1;i<=n;i++) cin>>a[i];
    for(int i=1;i<=n;i++)
    {
        if(!num[i])
        {
            cnt++;
            for(int j=i;!num[j];j=a[j])
            {
                num[j]=true;
            }
        }
    }
    cout<<n-cnt<<endl;
    return 0;
}
  • 9
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值