首页 > 其他分享 >代码随想录训练营第58天|统计相邻

代码随想录训练营第58天|统计相邻

时间:2024-10-16 20:46:47浏览次数:3  
标签:58 int graph 训练营 随想录 cin ++ visited include

110. 字符串接龙

#include <iostream>
#include <vector>
#include <string>
#include <unordered_set>
#include <unordered_map>
#include <queue>
using namespace std;
int main() {
    string beginStr, endStr, str;
    int n;
    cin >> n;
    unordered_set<string> strSet;
    cin >> beginStr >> endStr;
    for (int i = 0; i < n; i++) {
        cin >> str;
        strSet.insert(str);
    }

    // 记录strSet里的字符串是否被访问过,同时记录路径长度
    unordered_map<string, int> visitMap; // <记录的字符串,路径长度>

    // 初始化队列
    queue<string> que;
    que.push(beginStr);

    // 初始化visitMap
    visitMap[beginStr]=1;

    while(!que.empty()) {
        string word = que.front();
        que.pop();
        int path = visitMap[word]; // 这个字符串在路径中的长度

        // 开始在这个str中,挨个字符去替换
        for (int i = 0; i < word.size(); i++) {
            string newWord = word; // 用一个新字符串替换str,因为每次要置换一个字符

            // 遍历26的字母
            for (int j = 0 ; j < 26; j++) {
                newWord[i] = j + 'a';
                if (newWord == endStr) { // 发现替换字母后,字符串与终点字符串相同
                    cout <<  path + 1 << endl; // 找到了路径 
                    return 0;
                }
                // 字符串集合里出现了newWord,并且newWord没有被访问过
                if (strSet.count(newWord) && !visitMap.count(newWord)) {
                    // 添加访问信息,并将新字符串放到队列中
                    visitMap[newWord]= path + 1;
                    que.push(newWord);
                }
            }
        }
    }

    // 没找到输出0
    cout << 0 << endl;

}

采用广搜,第一次找到的一定就是最短的。寻找方式:遍历所有位置、所有可能得字符,得到的newWord必须在候选集中,同时之前没有被访问过,才会加入队列,进行下一层的搜索。

105. 有向图的完全可达性

#include <iostream>
#include <vector>
#include <list>
using namespace std;

void dfs(const vector<list<int>>& graph, int key, vector<bool>& visited) {
    visited[key] = true;
    list<int> keys = graph[key];
    for (int k : keys) {
        // 深度优先搜索遍历
        if(!visited[k])
            dfs(graph, k, visited);
    }
}

int main() {
    int n, m, s, t;
    cin >> n >> m;

    // 节点编号从1到n,所以申请 n+1 这么大的数组
    vector<list<int>> graph(n + 1); // 邻接表
    while (m--) {
        cin >> s >> t;
        // 使用邻接表 ,表示 s -> t 是相连的
        graph[s].push_back(t);
    }
    vector<bool> visited(n + 1, false);
    dfs(graph, 1, visited);
    //检查是否都访问到了
    for (int i = 1; i <= n; i++) {
        if (visited[i] == false) {
            cout << -1 << endl;
            return 0;
        }
    }
    cout << 1 << endl;
}

通过深搜更新标记数组visited,对于未访问过的key才会调用dfs,进入函数后首先就进行标记。

106. 岛屿的周长

#include <iostream>
#include <vector>
using namespace std;
int main() {
    int n, m;
    cin >> n >> m;
    vector<vector<int>> grid(n, vector<int>(m, 0));
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            cin >> grid[i][j];
        }
    }
    int sum = 0;    // 陆地数量
    int cover = 0;  // 相邻数量
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            if (grid[i][j] == 1) {
                sum++; // 统计总的陆地数量
                // 统计上边相邻陆地
                if(i - 1 >= 0 && grid[i - 1][j] == 1) cover++;
                // 统计左边相邻陆地
                if(j - 1 >= 0 && grid[i][j - 1] == 1) cover++;
                // 为什么没统计下边和右边? 因为避免重复计算
            }
        }
    }

    cout << sum * 4 - cover * 2 << endl;

}

本题不需dfs,只要求出相邻陆地个数即可,对每个新陆地只考虑左上是否存在相邻,右下的相邻可以归属到下一个陆地的左上方,以此避免重复计算。 

标签:58,int,graph,训练营,随想录,cin,++,visited,include
From: https://blog.csdn.net/jiyisuifeng1991/article/details/142824251

相关文章

  • 代码随想录算法训练营day17| 654.最大二叉树 617.合并二叉树 700.二叉搜索树中的搜
    学习资料:https://programmercarl.com/0654.最大二叉树.html#算法公开课用前序遍历构造二叉树二叉搜索树的特点,其左节点的值<每个节点的值<其右节点的值,且根节点的值大于它的左子树的所有节点的值,小于它右子树的所有节点的值,其他同理。二叉搜索树的搜索和验证时不关心遍历顺序,因......
  • ArmSoM-Sige7 成为首款支持 openSUSE 的 RK3588 设备
    随着嵌入式系统和开源软件的不断发展,越来越多的开发者和爱好者对高性能的开发板及其操作系统支持寄予厚望。在这一背景下,ArmSoM-Sige7 凭借其强大的硬件性能和广泛的软件兼容性,成为了市场的关注焦点。令人兴奋的是,ArmSoM-Sige7 已成为首款支持openSUSE的RK3588设备,为开发者......
  • 代码随想录算法训练营第一天|704二分查找、27移除元素、977有序数组的平方
    代码随想录算法训练营第一天|704二分查找、27移除元素、977有序数组的平方1Leetcode704二分查找题目链接:[704.二分查找](704.二分查找-力扣(LeetCode))文章链接:[代码随想录](代码随想录(programmercarl.com))视频链接:[手把手带你撕出正确的二分法|二分查找法|二分搜......
  • 西数SN580/SN770安装Windows 11 24H2蓝屏死机 下面是解决办法
    如果你使用的是西部数据SN580或SN770固态硬盘,则在安装或升级到Windows1124H2版后可能出现蓝屏死机问题。这两款固态硬盘都没有DRAM缓存模块,缓存模块充当数据中转站,可以在写入数据时预先将数据写入速度更快的缓存模块再向硬盘里写入。虽然微软还未发布该问题的详......
  • Project Euler 588 题解
    这玩意好像甚至有递推式……不太懂(为什么是图片?cnblogs第一个公式没渲染成功)时间复杂度是\(O(4^{\degF}\logK)\)的。#include<bits/stdc++.h>usingnamespacestd;#defineintlonglongconstintmaxn=100;intf[17][maxn],cur[10],al[4];intcalc(intK){ //cer......
  • CF1458D Flip and Reverse 题解
    思路由于它要求\(\text{01}\)数量相等,我们可以考虑站在前缀和的角度看待这个问题。我们将\(0\)看作负一,\(1\)看作一。可以把它化成一个折线图(方便观察)。观察一下它的操作实际上在干什么。容易发现,在折线图上,我们把操作的\([l,r]\)的整段折线reverse了一遍。同样的,......
  • 代码随想录算法训练营第42天 | 第九章动态规划 part2
    文章目录第十章单调栈part0242.接雨水示例数组:过程解释表格:过程解析:双指针法84.柱状图中最大的矩形双指针法单调栈法第十章单调栈part0242.接雨水接雨水这道题目是面试中特别高频的一道题,也是单调栈应用的题目,大家好好做做。建议是掌握双指针和单调栈,因......
  • P2580 于是他错误的点名开始了
    P2580于是他错误的点名开始了题目介绍给出\(n\)互不相同个字符串,询问\(m\)次,每次询问一个字符串是否存在,如存在判断是否已经询问过。\(n\le10^4,m\le10^5\)。做法1用map或unordered_map。用unordered_map时间复杂度为\(O(n+m)\),实测461ms。code做法2哈希......
  • 代码随想录算法训练营day16| 513.找树左下角的值 112.路径总和 106.从中序和后序
    学习资料:https://programmercarl.com/0513.找树左下角的值.html#算法公开课递归、回溯返回值:True/False,root构建二叉树TrueNode(root_value)513.找树左下角的值(实例变量self.result,self.maxdepth;找到叶子节点,若深度>self.maxdepth,则更新最大深度;只考虑左和右子树,用递归+......
  • 代码随想录算法训练营 | 188.买卖股票的最佳时机IV,309.最佳买卖股票时机含冷冻期,714.
    188.买卖股票的最佳时机IV题目链接:188.买卖股票的最佳时机IV文档讲解︰代码随想录(programmercarl.com)视频讲解︰买卖股票的最佳时机IV日期:2024-10-15想法:跟最佳时机III的区别在于dp[i][0]表示的是第i天没有操作,省去了会很麻烦。Java代码如下:classSolution{publicint......