面试笔试算法-搜索综合问题

这篇博客详细介绍了多个在线编程题目的解题思路,涉及搜索和图遍历算法,包括小明回家的距离计算、关系网络的最少认识人数、无向图的深度优先遍历、奇怪电梯的操作步数、警察找车的路线分析、奇怪电视的按钮操作序列最短长度、有效密码生成以及相遇问题的最短时间。通过这些题目,博主探讨了动态规划、二分查找、记忆化搜索等算法的应用。
摘要由CSDN通过智能技术生成

Oj81:小明回家

题目描述

小明看完了电影,是时候回家了,可是这时他突然得知小米之家的小米9现货开卖了,这款手机小明已经想了一个多月,知道这个消息后的他十分兴奋,一定要在回家之前先去小米之家买手机(城市中有一个或多个小米之家),请计算小明从电影院到任意一个小米之家买手机后回家的最短距离(只能朝上下左右四个方向行走,除了障碍物外,其他地方都可以通过),数据保证可以买完手机后回家。


输入

第 1 行两个数 n 和 m 表示地图有 n 行 m 列 2≤n,m≤2000 第 2 行至第 n+1 行为地图 其中 S 表示电影院 T 表示家 P 表示小米之家 . 为可以通过的点 # 为障碍物

输出

一个整数 表示小明从电影院去小米之家再回家的总距离


样例输入
5 5
.S...
###..
....T
.P##.
P....
样例输出
11

数据规模与约定

时间限制:5 s

内存限制:256 M

100% 的数据保证 2≤n,m≤2000

思路:

1、存储状态
2、起始状态
3、终止状态
4、状态转移
5、去重

在这里插入图片描述

#include<iostream>
#include <queue>
using namespace std;

// f表示是否去过手机店
struct node {
   
    int x, y, step, f;
};
// 去重数组check:
/*0:两种状态都没去过
  1:没手机的时候去过
  2:有手机的时候去过
  3:有手机和没手机都去过
*/ 
int n, m, check[2005][2005];
char mmap[2005][2005];
int dir[4][2] = {
   0, 1, 1, 0, 0, -1, -1, 0};

int main(int argc, char *grav[])
{
   
    cin >> n >> m;
    queue<node> que;
    for (int i = 1; i <= n; i++) {
   
        for (int j = 1; j <= m; j++) {
   
            cin >> mmap[i][j];
            if (mmap[i][j] == 'S') {
   
                que.push((node){
   i, j, 0, 0});
                check[i][j] = 1;
            }
        }
    }
    while (!que.empty()) {
   
        node temp = que.front();
        que.pop();
        for (int i = 0; i < 4; i++) {
   
            int x = temp.x + dir[i][0];
            int y = temp.y + dir[i][1];
            // 没手机的时候是否去过
            if ((check[x][y] & 1) && temp.f == 0) {
   
                continue;
            }
            // 有手机的时候是否去过
            if ((check[x][y] & 2) && temp.f == 1) {
   
                continue;
            }
            if (mmap[x][y] == 'T' && temp.f == 1) {
   
                cout << temp.step + 1 << endl;
                return 0;
            }
            if (mmap[x][y] == '.' || mmap[x][y] == 'S' || mmap[x][y] == 'T') {
   
                que.push((node){
   x, y, temp.step + 1, temp.f});
                check[x][y] += temp.f + 1;
            }
            if (mmap[x][y] == 'P') {
   
                que.push((node){
   x, y, temp.step + 1, 1});
                check[x][y] = 3;
            }
        }
    }
    cout << -1 << endl;
    return 0;
}

Oj528:关系网络

题目描述

有 n 个人,编号为 1∼n。其中有一些人互相认识,现在 x 想要认识 y,可以通过他所认识的人来认识更多的人(如果 a,b 相识,a,c 相识,那么 b 可以通过 a 来认识 c),求 x 最少需要通过多少中间人才能认识 y。


输入

第一行三个整数 n,x,y。(1≤x,y≤n≤100)

接下来是一个 n∗n 的邻接矩阵,a[i,j]=1 则说明 i,j 相识,=0 则不相识,保证 a[i,j]=a[j,i] 且 a[i,i]=0。

输出

输出一个数,表示最少人数,若无法相识,输出 0。


样例输入
5 1 5
0 1 0 0 0
1 0 1 1 0
0 1 0 1 0
0 1 1 0 1
0 0 0 1 0
样例输出
2

数据规模与约定

时间限制:1 s
内存限制:256 M
100% 的数据保证 1≤x,y≤n≤100

思路:

在这里插入图片描述

代码演示:
#include<iostream>
#include <queue>
using namespace std;
struct node {
   
    int now, step;
};
int n, x, y, check[105], arr[105][105];
int main(int argc, char *grav[])
{
   
    cin >> n >> x >> y;
    for (int i <
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值