当前位置: 首页 > news >正文

[洛谷刷题8]

P1913 L国的战斗之伞兵(标准的搜索题 BFS or DFS)

https://www.luogu.com.cn/problem/P1913

题目背景

L 国即将与 I 国发动战争!!

题目描述

为了在敌国渗透作战,指挥官决定:派出伞兵前往敌国!然而敌国的风十分强烈,能让伞兵在同一高度不停转悠,直到被刮到一个无风区……(可怜的小兵)

输入格式

第一行: n , m n,m n,m 两个正整数,表示敌国的大小。

以下 n n n 行,每行 m m m 个字符,u 表示风向北吹;d 表示风向南吹;l 表示风向西吹;r 表示风向东吹;o 表示无风。(上北下南,左西右东)

输出格式

一个数:表示有几个点可以放下伞兵。

输入输出样例 #1

输入 #1

5 5
rrrrr
rdddr
rroll
uuuuu
uuuuu

输出 #1

19

说明/提示

数据范围:

1 ≤ n ≤ 1000 1 \leq n \leq 1000 1n1000 1 ≤ m ≤ 1000 1 \leq m \leq 1000 1m1000

解题思路

问题分析

题目要求计算敌国地图上可以投放伞兵的点的数量。伞兵在有风的区域会被风不断刮动,直到进入无风区(标记为o)。因此,可以投放伞兵的点是那些可以通过风的引导最终到达无风区的点。

解决方案

广度优先搜索(BFS)

  • BFS 适用于从多个起点开始的层次遍历,能有效找到所有可达的节点。
  • 将所有无风区(o)作为起点,放入队列中。
  • 从这些起点开始,按照风的方向访问相邻的节点,标记可以到达的节点。
  • 最终统计所有被标记的节点数量,即为可以投放伞兵的点的数量。

深度优先搜索(DFS)

  • DFS 从每个无风区(o)出发,递归访问所有可以通过风的引导到达的节点。
  • 对于每个无风区,使用 DFS 遍历所有可达的节点,并标记这些节点。
  • 最终统计所有被标记的节点数量。

BFS 实现思路

  1. 初始化

    • 读取地图的大小 nm
    • 使用一个队列存储所有无风区的坐标。
    • 初始化访问标记数组 vis,标记所有无风区为已访问。
  2. BFS 遍历

    • 从队列中取出一个节点,统计为可投放点。
    • 根据当前节点的风向,访问相邻的节点:
      • 如果风向为 u,则向下移动(行加1)。
      • 如果风向为 d,则向上移动(行减1)。
      • 如果风向为 l,则向右移动(列加1)。
      • 如果风向为 r,则向左移动(列减1)。
    • 将相邻的未访问节点加入队列,并标记为已访问。
  3. 统计结果

    • 遍历所有节点,统计被标记的节点数量。

DFS 实现思路

  1. 初始化

    • 读取地图的大小 nm
    • 初始化访问标记数组 vis
  2. DFS 遍历

    • 对于每个无风区(o),调用 DFS 函数。
    • 在 DFS 函数中,标记当前节点为已访问。
    • 根据当前节点的风向,递归访问相邻的节点:
      • 如果风向为 u,则向下移动(行加1)。
      • 如果风向为 d,则向上移动(行减1)。
      • 如果风向为 l,则向右移动(列加1)。
      • 如果风向为 r,则向左移动(列减1)。
    • 确保递归调用时节点在地图范围内且未被访问。
  3. 统计结果

    • 遍历所有节点,统计被标记的节点数量。
AC Code(BFS)
#include <bits/stdc++.h>
using namespace std;const int N = 1e3+9;
char mp[N][N];
bool vis[N][N];
int ans = 0;void solve(){int n,m;cin >> n >> m;queue<array<int,2>> q;for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){cin >> mp[i][j];if(mp[i][j]=='o'){q.push({i,j});vis[i][j] = true;}}}//lambda函数auto bfs = [&]()->void{while(!q.empty()){array<int,2> tmp = q.front();q.pop();ans++;if(mp[tmp[0]+1][tmp[1]]=='u'&&!vis[tmp[0]+1][tmp[1]]){q.push({tmp[0]+1,tmp[1]});vis[tmp[0]+1][tmp[1]]=true;}if(mp[tmp[0]-1][tmp[1]]=='d'&&!vis[tmp[0]-1][tmp[1]]){q.push({tmp[0]-1,tmp[1]});vis[tmp[0]-1][tmp[1]]=true;}if(mp[tmp[0]][tmp[1]-1]=='r'&&!vis[tmp[0]][tmp[1]-1]){q.push({tmp[0],tmp[1]-1});vis[tmp[0]][tmp[1]-1]=true;}if(mp[tmp[0]][tmp[1]+1]=='l'&&!vis[tmp[0]][tmp[1]+1]){q.push({tmp[0],tmp[1]+1});vis[tmp[0]][tmp[1]+1]=true;}}};bfs();cout << ans;
}int main(){ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);int t=1;//cin >> t;while(t--){solve();}return 0;
}
AC Code(DFS)
#include<iostream>
using namespace std;const int N = 1e3+9;
char mp[N][N];
bool vis[N][N];
int ans = 0;void dfs(int i,int j){  vis[i][j]=true;if(mp[i+1][j]=='u'){dfs(i+1,j);}if(mp[i-1][j]=='d'){dfs(i-1,j);}if(mp[i][j+1]=='l'){dfs(i,j+1);}if(mp[i][j-1]=='r'){dfs(i,j-1);}
}void solve(){int n,m;cin >> n >> m;for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){cin >> mp[i][j];}}for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){if(mp[i][j]=='o'){dfs(i,j);}}}for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){if(vis[i][j]){ans++;}}}cout << ans;
}int main(){ ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);int t=1;//cin >> t;while(t--){solve();}return 0;
}

P2110 欢总喊楼记

https://www.luogu.com.cn/problem/P2110

题目描述

诗经有云:

关关雎鸠,在河之洲。窈窕淑女,君子好逑。

又是一个被风吹过的夏天……一日欢总在图书馆中自习,抬起头来,只见一翩跹女子从面前飘过,真是回眸一笑百媚生,六宫粉黛无颜色!一阵诗情涌上欢总心头,他顺手写下那诗句:

啊,你是爱,是暖,是希望,你是人间四月天!

任时光匆匆而过,欢总一直没能忘记那女子。人言单思苦,欢总偏单思。夜夜难入梦,此心淑可知。偶然一次机会,欢总得知了那女孩的信息。一日,欢总终于鼓起了勇气,他向她表白!

那晚的夜色格外美丽,欢总在楼下慷慨激昂,气氛浪漫而感人。女孩有点心动了,但是直接答应是不是有点太不矜持了呢?于是,她想难难欢总,看看他到底有多少诚意。

女孩给出了两个整数 L 和 R,她要欢总数出到底有多少个这样的 X:L <= X <= R,且 X 的最高位与最低位相等(十进制下)。比如,2、101、329873可以是这样的 X,而23、4567就不是。

孩子们,欢总下辈子的幸福生活就靠你们帮忙了!

输入格式

一行,这一行包括两个整数 L 和 R。

输出格式

一行,这一行包括一个整数,即满足所述性质的 X 的个数。

输入输出样例 #1

输入 #1

2 47

输出 #1

12

说明/提示

【数据规模】

50% 1<=L<=R<=10^6

100% 1<=L<=R<=10^18

题目大意

女孩给出 L L L R R R 两个数,求 [ L , R ] [L,R] [L,R] X X X 的个数,而 X X X 必须满足最高位与最低位相等这个条件(十进制下)。

分析
我们可以发现:
如果直接暴力枚举,必然超时(请看数据范围)。
所以,我们可以通过仔细观察发现:题目问的问题只限制最高位与最低位相等,那么这就是此题的突破口。
接着,我们假设已经确定了最高位。
那么此时的最低位只有 1 种可能(因为最高位与最低位相等)。
这就说明,每 10 个数中,只有 1 个符合题目条件的 X X X
由此得出本题做法(见下)。

具体做法
[ L , R ] [L,R] [L,R] 中的数字分成每 10 个 1 组,然后就可以得到: [ 1 , N ] [1,N] [1,N] X X X 的个数为 N ÷ 10 + 9 N\div10+9 N÷10+9。当然,还有特殊情况,比如最低位小于最高位时,应当 − 1 -1 1

解释一下:
加的 9 是因为 [ 1 , 9 ] [1,9] [1,9] 这个区间中有 9 个 X X X

注意事项

AC Code
#include<bits/stdc++.h>
using namespace std;typedef long long ll;ll solve(ll n){if(n<10){return n;}ll sum = n/10+9;ll p = n;while(p > 9){p /= 10;}ll q = n%10;if(q < p){sum--;}return sum;
}
int main(){ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);ll l,r;cin >> l >> r;cout << solve(r) - solve(l-1);return 0;
}

相关文章:

  • Redis三种高可用模式的使用场景及特点的详细介绍
  • # KVstorageBaseRaft-cpp 项目 RPC 模块源码学习
  • JVM中的安全点是什么,作用又是什么?
  • 苍穹外卖-创建阿里云oss工具包
  • 缓存(4):常见缓存 概念、问题、现象 及 预防问题
  • 关于物联网的基础知识(一)
  • 串口通讯
  • 【东枫科技】使用LabVIEW进行NVIDIA CUDA GPU 开发
  • 数据库分库分表实战指南:从原理到落地
  • ARMV8 RK3399 u-boot TPL启动流程分析 --start.S
  • JVM-类加载子系统
  • 机器学习极简入门:从基础概念到行业应用
  • 锚定基础与拥抱融合:C 语言在编程教育与技术社区的破圈之路
  • 全模态具身智能:从 VLM 到 MLLM
  • Java大师成长计划之第18天:Java Memory Model与Volatile关键字
  • 单片机-STM32部分:13、PWM
  • STM32智能窗帘系统:从零到一的开发实战
  • 开源字体设计工具字玩 FontPlayer
  • “爱生活”小项目问题总结
  • 【大模型】解决最新的Dify1.3.1版本 无法基于Ollama成功添加模型
  • 广东省中医院脾胃病科大科主任张北平病逝,年仅52岁
  • 专访|导演刘江:给谍战题材注入现实主义的魂
  • 秦洪看盘|预期改善,或迎来新的增量资金
  • 港股持续拉升:恒生科技指数盘中涨幅扩大至6%,恒生指数涨3.3%
  • 浙江首个核酸药谷落子杭州,欢迎订阅《浪尖周报》第23期
  • 种罂粟喂鸡防病?四川广元一村民非法种植毒品原植物被罚​