图论day58|110.字符串接龙(卡码网)【难度等同于104】、105.有向图的完全可达性(卡码网)【深搜的终止条件要注意!】、106.岛屿的周长(卡码网)【打破惯性思维】

图论day58|110.字符串接龙(卡码网)【难度等同于104】、105.有向图的完全可达性(卡码网)【深搜的终止条件要注意!】、106.岛屿的周长(卡码网)【打破惯性思维】

110.字符串接龙(卡码网)【难度等同于104】

题目描述

字典 strList 中从字符串 beginStr 和 endStr 的转换序列是一个按下述规格形成的序列:

  1. 序列中第一个字符串是 beginStr。
  2. 序列中最后一个字符串是 endStr。
  3. 每次转换只能改变一个字符。
  4. 转换过程中的中间字符串必须是字典 strList 中的字符串,且strList里的每个字符串只用使用一次。

给你两个字符串 beginStr 和 endStr 和一个字典 strList,找到从 beginStr 到 endStr 的最短转换序列中的字符串数目。如果不存在这样的转换序列,返回 0。

输入描述

第一行包含一个整数 N,表示字典 strList 中的字符串数量。 第二行包含两个字符串,用空格隔开,分别代表 beginStr 和 endStr。 后续 N 行,每行一个字符串,代表 strList 中的字符串。

输出描述

输出一个整数,代表从 beginStr 转换到 endStr 需要的最短转换序列中的字符串数量。如果不存在这样的转换序列,则输出 0。

输入示例

6
abc def
efc
dbc
ebc
dec
dfc
yhn

输出示例

4

提示信息

从 startStr 到 endStr,在 strList 中最短的路径为 abc -> dbc -> dec -> def,所以输出结果为 4,如图:

img

数据范围:

2 <= N <= 500

在这里插入图片描述

#include <iostream>
#include <vector>
#include <queue>
#include <unordered_map>
#include <unordered_set>
#include <string>
using namespace std;

int main()
{
    int n;
    cin>>n;

    string beginStr,endStr,str;

    unordered_set<string> strList;

    cin>>beginStr>>endStr;
    for(int i=0;i<n;i++)
    {
        cin>>str;
        strList.insert(str);
    }

    unordered_map<string,int> strMap;

    queue<string> que;
    que.push(beginStr);
    strMap[beginStr]=1;

    while(!que.empty())
    {
        string word=que.front();
        que.pop();
        int path=strMap[word];
        for(int i=0;i<word.size();i++)
        {
            string newWord=word;
            for(int j=0;j<26;j++)
            {
                newWord[i]='a'+j;
                if(newWord==endStr)
                {
                    cout<<path+1<<endl;
                    return 0;
                }
                if(strList.find(newWord)!=strList.end()&&
                   strMap.find(newWord)==strMap.end())
                {
                    que.push(newWord);
                    strMap[newWord]=path+1;
                }
            }
        }
    }
    cout<<0<<endl;
}

105.有向图的完全可达性(卡码网)【深搜的终止条件要注意!】

题目描述

给定一个有向图,包含 N 个节点,节点编号分别为 1,2,…,N。现从 1 号节点开始,如果可以从 1 号节点的边可以到达任何节点,则输出 1,否则输出 -1。

输入描述

第一行包含两个正整数,表示节点数量 N 和边的数量 K。 后续 K 行,每行两个正整数 s 和 t,表示从 s 节点有一条边单向连接到 t 节点。

输出描述

如果可以从 1 号节点的边可以到达任何节点,则输出 1,否则输出 -1。

输入示例

4 4
1 2
2 1
1 3
2 4

输出示例

1

提示信息

img

从 1 号节点可以到达任意节点,输出 1。

数据范围:

1 <= N <= 100;
1 <= K <= 2000。
在这里插入图片描述

#include <iostream>
#include <vector>
using namespace std;
int n,k;
void dfs(const vector<vector<int>>graph,vector<bool>& visited,int key)
{
    if(visited[key]==true)
        return;
    visited[key]=true;
    for(int i=1;i<=n;i++)
        if(graph[key][i]==1)
            dfs(graph,visited,i);
}
int main()
{
    int s,t;
    cin>>n>>k;
    vector<vector<int>> graph(n+1,vector<int>(n+1,0));
    for(int i=0;i<k;i++)
    {
        cin>>s>>t;
        graph[s][t]=1;
    }

    vector<bool> visited(n+1,false);
    dfs(graph,visited,1);
    for(int i=1;i<=n;i++)
    {
        if(visited[i]==false)
        {
            cout<<-1<<endl;
            return 0;
        }
    }
    cout<<1<<endl;
}

106.岛屿的周长(卡码网)【打破惯性思维】

题目描述

给定一个由 1(陆地)和 0(水)组成的矩阵,岛屿是被水包围,并且通过水平方向或垂直方向上相邻的陆地连接而成的。

你可以假设矩阵外均被水包围。在矩阵中恰好拥有一个岛屿,假设组成岛屿的陆地边长都为 1,请计算岛屿的周长。岛屿内部没有水域。

输入描述

第一行包含两个整数 N, M,表示矩阵的行数和列数。之后 N 行,每行包含 M 个数字,数字为 1 或者 0,表示岛屿的单元格。

输出描述

输出一个整数,表示岛屿的周长。

输入示例

5 5
0 0 0 0 0 
0 1 0 1 0
0 1 1 1 0
0 1 1 1 0
0 0 0 0 0

输出示例

14

提示信息

img

岛屿的周长为 14。

数据范围:

1 <= M, N <= 50。

在这里插入图片描述

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

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

    vector<vector<int>> grid(n+1,vector<int>(m+1,0));

    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            cin>>grid[i][j];

    int dir[4][2]={1,0,-1,0,0,-1,0,1};
    int result=0;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        {
            if(grid[i][j]==1)
            {
                for(int k=0;k<4;k++)
                {
                    int nexti=i+dir[k][0];
                    int nextj=j+dir[k][1];
                    if(nexti<=0||nexti>=grid.size()||nextj<=0||nextj>=grid[1].size()||grid[nexti][nextj]==0)
                        result++;
                }
            }
        }
    cout<<result<<endl;

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值