代码随想录第52天

发布于:2024-12-21 ⋅ 阅读:(16) ⋅ 点赞:(0)

110.字符串接龙

#include<iostream>
#include<unordered_map>
#include<queue>
using namespace std;
// 定义一个类用来解决本道题
class Xxc {
private:
    // 用来记录可以每个字符可以改变的可能
    static char libs[26];
public:
    static int xxc(unordered_map<string, bool> &um, string s1, string s2) {
        queue<string> que;  // 用来广搜的队列
        que.push(s1);  // 将起始的字符串放进去
        int cnt = 1;  // 起始路径为1
        while (!que.empty()) {
            int len = que.size();
            for (int i = 0; i < len; ++i) {
                // 取出每一轮要搜索的字符串,每一轮后路径加一
                string cur = que.front();
                int len_cur = cur.size();
                que.pop();
                // 如果当前字符串与终点字符串相同,就代表找到了答案
                if (cur == s2) return cnt;
                // 两层循环的作用分别为搜索一个字符串每一个位置的字符以及每一位可能变化的可能
                // 因为每一个字符串每一次改变最多只能改变一位,而字符串的长度为len_cur
                // 所以从第0位开始,一直到len_cur都可能会是改变的目标
                for (int j = 0; j < len_cur; ++j) {
                    // 里层循环代表每一位可能会做出的改变,一共有25种可能
                    for (int k = 0; k < 26; ++k) {
                        // 如果改变后的字符串与自身相同,没意义,则不改变
                        if (cur[j] != libs[k]) {
                            // 对字符串某一位做出相应地改变
                            char temp = cur[j];
                            cur[j] = libs[k];
                            // 对改变后的字符串进行判断,是否之前已经得到过该字符串,
                            // 如果得到了,则说明产生了回路,没意义,不用将其加入下一轮的队列
                            if (um[cur]) {
                                // 找到一个新的存在于字典中的字符串,将其加入队列
                                que.push(cur);
                                // 标记该字符串已经加入过,之后再遇到不用理会了
                                um[cur] = false;
                            }
                            // 遍历完这一位会做出的所有符合规则的改变后,将其还原,
                            // 然后开始下一位的改变
                            cur[j] = temp;
                        }
                    }
                }
            }
            // 每一轮结束后,就可以将路径加一
            ++cnt;
        }
        return 0;
    }
};
// 初始化每一位可能做出的改变集合
char Xxc::libs[] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
                    'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
                    'u', 'v', 'w', 'x', 'y', 'z'};
int main() {
    int n;
    cin >> n;
    string s1, s2;
    cin >> s1 >> s2;
    // 记录符合规则的字符串,并记录是否访问过
    // true表示可以到达这条路,false反之
    unordered_map<string, bool> um;
    for (int i = 0; i < n; ++i) {
        string temp;
        cin >> temp;
        um[temp] = true;
    }
    cout << Xxc::xxc(um, s1, s2);
    return 0;
}

有向图的完全可达性

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int nodeNum = in.nextInt();
        int edgeNum = in.nextInt();
        int[][] graph = new int[nodeNum][nodeNum];
        for (int i = 0; i < edgeNum; i++) {
            int node1 = in.nextInt() - 1;
            int node2 = in.nextInt() - 1;
            graph[node1][node2] = 1;
        }
        boolean[] visited = new boolean[nodeNum];
        int count = 0;
        Deque<Integer> path = new ArrayDeque<>();
        visited[0] = true;
        count += 1;
        path.offerLast(0);
        while (path.size() != 0) {
            Integer node = path.pollFirst();
            for (int i = 0; i < graph[node].length; i++) {
                if (graph[node][i]==0) {
                    continue;
                }
                if (visited[i]) {
                    continue;
                }
                count += 1;
                visited[i] = true;
                path.offerLast(i);
            }
        }
        if (count!=visited.length) {
            System.out.println(-1);
        } else {
            System.out.println(1);
        }
    }
}

106.岛屿的周长

#include <iostream>
#include <vector>

int main() {
    int n, m;
    int result = 0;
    std::cin >> n >> m;
    // n+2行m+2列, 四周各加一行padding
    std::vector<std::vector<int>> matrix(n + 2, std::vector<int>(m + 2, 0));
    // 读入
    for(int i = 1; i < n + 1; i++) {
        for(int j = 1; j < m + 1; j++) {
            std::cin >> matrix[i][j];
        }
    }
    // 遍历
    // 结果收集规则,当前位置是1时收集当前位置上下左右四个位置的0的个数
    // 对于1在边界的情况,初始化时加了padding,可以直接用相同逻辑处理不会越界访问
    for(int i = 1; i < n + 1; i++) {
        for(int j = 1; j < m + 1; j++) {
            if(matrix[i][j] == 1) {
                if(matrix[i - 1][j] == 0) result++;
                if(matrix[i][j - 1] == 0) result++;
                if(matrix[i + 1][j] == 0) result++;
                if(matrix[i][j + 1] == 0) result++;
            }
        }
    }
    // 输出
    std::cout << result << std::endl;
    return 0;
}