数据结构与算法-图论-欧拉路径和欧拉回路(有向图和无向图,骑马修栅栏,单词游戏 play on words)详细代码注解

基础前置知识:

有向图:

欧拉路径:

定义:在有向图中,从一个顶点出发,经过每条边恰好一次,并且遍历所有顶点的路径称为有向图的欧拉路径。

特征:有向图存在欧拉路径,当且仅当该图是连通的,且除了两个顶点外其余顶点的入度等于出度。这两个特殊顶点中,一个顶点的入度比出度大 1(终点),另一个顶点的出度比入度大 1(起点)。如果全部点的入度和出度数都是相等的也可以。

欧拉回路:

定义:在有向图中,从一个顶点出发,经过每条边恰好一次,最后回到起始顶点的路径称为有向图的欧拉回路。

特征:有向图存在欧拉回路,当且仅当该图是连通的,且所有顶点的入度等于出度。

无向图

欧拉路径:

定义:在无向图中,从一个顶点出发,经过每条边恰好一次,并且遍历所有顶点的路径称为无向图的欧拉路径。

特征:无向图存在欧拉路径,当且仅当该图是连通的,且图中奇度顶点(度数为奇数的顶点)的个数为 0 或 2。若奇度顶点个数为 0,则可以从任意顶点出发;若奇度顶点个数为 2,则必须从其中一个奇度顶点出发,到另一个奇度顶点结束。

欧拉回路:

定义:在无向图中,从一个顶点出发,经过每条边恰好一次,最后回到起始顶点的路径称为无向图的欧拉回路。

特征:无向图存在欧拉回路,当且仅当该图是连通的,且所有顶点的度数均为偶数

4个板子题

有向图的欧拉路径:

题目描述

求有向图字典序最小的欧拉路径。

输入格式

第一行两个整数 n,m 表示有向图的点数和边数。

接下来 m 行每行两个整数 u,v 表示存在一条 u→v 的有向边。

输出格式

如果不存在欧拉路径,输出一行 No。

否则输出一行 m+1 个数字,表示字典序最小的欧拉路径。

代码:

#include <bits/stdc++.h>

using namespace std;

const int N = 100005;

// 存储图的邻接表

vector<int> g[N];

// 记录每个节点的入度

int in[N];

// 记录每个节点的出度

int out[N];

// 存储欧拉路径

int s[N];

int top=0;

// 深度优先搜索函数,用于寻找欧拉路径

void dfs(int u) {

    // 遍历从节点 u 出发的所有边

    while (!g[u].empty()) {

        // 取出字典序最小的邻接节点

        int v = g[u].back();

        g[u].pop_back();

        // 递归调用 dfs 函数继续搜索

        dfs(v);

    }

    // 将节点 u 加入欧拉路径

    s[++top]=u;

}

int main() {

    int n, m;

    // 读取图的点数 n 和边数 m

    cin >> n >> m;

    // 读取每条边的信息,并更新入度和出度

    for (int i = 0; i < m; i++) {

        int u, v;

        cin >> u >> v;

        // 将边 (u, v) 加入邻接表

        g[u].push_back(v);

        // 节点 v 的入度加 1

        in[v]++;

        // 节点 u 的出度加 1

        out[u]++;

    }

    // 对每个节点的邻接表进行排序,以保证按字典序遍历

    for (int i = 1; i <= n; i++) {

        sort(g[i].begin(), g[i].end(), greater<int>());

    }

    

    // 寻找可能的起始节点

    int start = 1;

    int cnt = 0;

    bool flag = true;

    for (int i = 1; i <= n; i++) {

        if (out[i] - in[i] == 1) {

            // 出度比入度大 1 的节点作为起始节点

            start = i;

            cnt++;

        } else if (out[i] - in[i] == -1) {

            cnt++;

        } else if (out[i] != in[i]) {

            // 若存在节点入度和出度差值不为 0、1 或 -1,则不存在欧拉路径

            flag = false;

            break;

        }

    }

    // 欧拉路径要求要么所有节点入度等于出度(欧拉回路),要么有两个节点入度和出度差值为 1 和 -1

    if (cnt != 0 && cnt != 2) {

        flag = false;

    }

    if (!flag) {

        // 若不存在欧拉路径,输出 No

        cout << "No" << endl;

    } else {

        // 从起始节点开始深度优先搜索

        dfs(start);

        // 输出欧拉路径

        while (top) {

            cout << s[top--];

            if (top) {

                cout << " ";

            }

        }

        cout << endl;

    }

    return 0;

}

无向图的欧拉路径:

重点是度数的奇偶性

同样的上面的题,但是改成无向图

题目描述

求无向图字典序最小的欧拉路径。

输入格式

第一行两个整数 n,m 表示有向图的点数和边数。

接下来 m 行每行两个整数 u,v 表示存在一条 u→v 的有向边。

输出格式

如果不存在欧拉路径,输出一行 No。

否则输出一行 m+1 个数字,表示字典序最小的欧拉路径。

代码:

#include <bits/stdc++.h>

using namespace std;

const int N = 100005;

// 存储图的邻接表

vector<int> g[N];

// 记录每个节点的度数

int degree[N];

// 存储欧拉路径

int s[N];int top = 0;

// 深度优先搜索函数,用于寻找欧拉路径

void dfs(int u) {

    // 遍历从节点 u 出发的所有边

    while (!g[u].empty()) {

        // 取出字典序最小的邻接节点

        int v = g[u].back();

        // 从 u 的邻接表中删除 v,同时也从 v 的邻接表中删除 u(无向图)

        g[u].pop_back();

        it = find(g[v].begin(), g[v].end(), u);

        if (it != g[v].end()) {

            g[v].erase(it);

        }

        // 递归调用 dfs 函数继续搜索

        dfs(v);

    }

    // 将节点 u 加入欧拉路径

s[++top] = u;

}

int main() {

    int n, m;

    // 读取图的点数 n 和边数 m

    cin >> n >> m;

    // 读取每条边的信息,并更新节点度数

    for (int i = 0; i < m; i++) {

        int u, v;

        cin >> u >> v;

        // 将边 (u, v) 加入邻接表(无向图,双向添加)

        g[u].push_back(v);

        g[v].push_back(u);

        // 节点 u 和 v 的度数都加 1

        degree[u]++;

        degree[v]++;

    }

    // 对每个节点的邻接表进行排序,以保证按字典序遍历

    for (int i = 1; i <= n; i++) {

        sort(g[i].begin(), g[i].end(), greater<int>());

    }

    // 寻找可能的起始节点

    int start = 1;

    int oddDegreeCount = 0;

    bool flag = true;

    for (int i = 1; i <= n; i++) {

        if (degree[i] % 2 == 1) {

            // 度数为奇数的节点

            oddDegreeCount++;

            start = i;

        }

        if (degree[i] % 2 == 1 && oddDegreeCount > 2) {

            // 若奇数度数节点超过 2 个,则不存在欧拉路径

            flag = false;

            break;

        }

    }

    if (oddDegreeCount != 0 && oddDegreeCount != 2) {

        // 奇数度数节点不为 0 或 2 时,不存在欧拉路径

        flag = false;

    }

    if (!flag) {

        // 若不存在欧拉路径,输出 No

        cout << "No" << endl;

    } else {

        // 从起始节点开始深度优先搜索

        dfs(start);

        // 输出欧拉路径

        while (top) {

            cout << s[top--];

            if (top) {

                cout << " ";

            }

        }

        cout << endl;

    }

return 0;

}

有向图的欧拉回路:

题目描述

求有向图字典序最小的欧拉回路。

输入格式

第一行两个整数 n,m 表示有向图的点数和边数。

接下来 m 行每行两个整数 u,v 表示存在一条 u→v 的有向边。

输出格式

如果不存在欧拉路径,输出一行 No。

否则输出一行 m+1 个数字,表示字典序最小的欧拉路径。

代码:

#include <bits/stdc++.h>

using namespace std;

const int N = 100005;

// 存储图的邻接表

vector<int> g[N];

// 记录每个节点的入度

int in[N];

// 记录每个节点的出度

int out[N];

// 存储欧拉回路

int s[N];int top = 0;

// 深度优先搜索函数,用于寻找欧拉回路

void dfs(int u) {

    // 遍历从节点 u 出发的所有边

    while (!g[u].empty()) {

        // 取出字典序最小的邻接节点

        int v = g[u].back();

        g[u].pop_back();

        // 递归调用 dfs 函数继续搜索

        dfs(v);

    }

    // 将节点 u 加入欧拉回路

    s[++top] = u;}

int main() {

    int n, m;

    // 读取图的点数 n 和边数 m

    cin >> n >> m;

    // 读取每条边的信息,并更新入度和出度

    for (int i = 0; i < m; i++) {

        int u, v;

        cin >> u >> v;

        // 将边 (u, v) 加入邻接表

        g[u].push_back(v);

        // 节点 v 的入度加 1

        in[v]++;

        // 节点 u 的出度加 1

        out[u]++;

    }

    // 对每个节点的邻接表进行排序,以保证按字典序遍历

    for (int i = 1; i <= n; i++) {

        sort(g[i].begin(), g[i].end(), greater<int>());

    }

    // 检查是否存在欧拉回路  和上面唯一不一样的地方

    bool flag = true;

    for (int i = 1; i <= n; i++) {

        if (in[i] != out[i]) {

            // 若存在节点入度和出度不相等,则不存在欧拉回路

            flag = false;

            break;

        }

    }

    if (!flag) {

        // 若不存在欧拉回路,输出 No

        cout << "No" << endl;

    } else {

        // 从节点 1 开始深度优先搜索

        dfs(1);

        // 输出欧拉回路

        while (top) {

            cout << s[top--];

            if (top) {

                cout << " ";

            }

        }

        cout << endl;

    }

return 0;

}

无向图的欧拉回路

题目描述

求无向图字典序最小的欧拉回路。

输入格式

第一行两个整数 n,m 表示有向图的点数和边数。

接下来 m 行每行两个整数 u,v 表示存在一条 u→v 的有向边。

输出格式

如果不存在欧拉路径,输出一行 No。

否则输出一行 m+1 个数字,表示字典序最小的欧拉路径。

代码:

#include <bits/stdc++.h>

using namespace std;

const int N = 100005;

// 存储图的邻接表

vector<int> g[N];// 记录每个节点的度数int degree[N];// 存储欧拉回路int s[N];int top = 0;

// 深度优先搜索函数,用于寻找欧拉回路void dfs(int u) {

    // 遍历从节点 u 出发的所有边

    while (!g[u].empty()) {

        // 取出字典序最小的邻接节点

        int v = g[u].back();

        // 从 u 的邻接表中删除 v,同时也从 v 的邻接表中删除 u(无向图)

        g[u].pop_back();

        auto it = find(g[v].begin(), g[v].end(), u);

        if (it != g[v].end()) {

            g[v].erase(it);

        }

        // 递归调用 dfs 函数继续搜索

        dfs(v);

    }

    // 将节点 u 加入欧拉回路

    s[++top] = u;}

int main() {

    int n, m;

    // 读取图的点数 n 和边数 m

    cin >> n >> m;

    // 读取每条边的信息,并更新节点度数

    for (int i = 0; i < m; i++) {

        int u, v;

        cin >> u >> v;

        // 将边 (u, v) 加入邻接表(无向图,双向添加)

        g[u].push_back(v);

        g[v].push_back(u);

        // 节点 u 和 v 的度数都加 1

        degree[u]++;

        degree[v]++;

    }

    // 对每个节点的邻接表进行排序,以保证按字典序遍历

    for (int i = 1; i <= n; i++) {

        sort(g[i].begin(), g[i].end(), greater<int>());

    }

    // 检查是否存在欧拉回路  改变的地方

    bool flag = true;

    for (int i = 1; i <= n; i++) {

        if (degree[i] % 2 != 0) {

            // 若存在节点度数为奇数,则不存在欧拉回路

            flag = false;

            break;

        }

    }

    if (!flag) {

        // 若不存在欧拉回路,输出 No

        cout << "No" << endl;

    } else {

        // 从节点 1 开始深度优先搜索

        dfs(1);

        // 输出欧拉回路

        while (top) {

            cout << s[top--];

            if (top) {

                cout << " ";

            }

        }

        cout << endl;

    }

return 0;

}

练习题:

USACO3.3 骑马修栅栏 

题目背景

Farmer John 每年有很多栅栏要修理。他总是骑着马穿过每一个栅栏并修复它破损的地方。

题目描述

John 是一个与其他农民一样懒的人。他讨厌骑马,因此从来不两次经过一个栅栏。

John 的农场上一共有 m 个栅栏,每一个栅栏连接两个顶点,顶点用 1 到 500 标号(虽然有的农场并没有那么多个顶点)。一个顶点上至少连接 1 个栅栏,没有上限。两顶点间可能有多个栅栏。所有栅栏都是连通的(也就是你可以从任意一个栅栏到达另外的所有栅栏)。John 能从任何一个顶点(即两个栅栏的交点)开始骑马,在任意一个顶点结束。

你需要求出输出骑马的路径(用路上依次经过的顶点号码表示),使每个栅栏都恰好被经过一次。如果存在多组可行的解,按照如下方式进行输出:如果把输出的路径看成是一个 500 进制的数,那么当存在多组解的情况下,输出 500 进制表示法中最小的一个 (也就是输出第一位较小的,如果还有多组解,输出第二位较小的,以此类推)。

输入数据保证至少有一个解。

输入格式

第一行一个整数 m,表示栅栏的数目。

从第二行到第 (m+1) 行,每行两个整数 u,v,表示有一条栅栏连接 u,v 两个点。

输出格式

共 (m+1) 行,每行一个整数,依次表示路径经过的顶点号。注意数据可能有多组解,但是只有上面题目要求的那一组解是认为正确的。

数据保证至少有一组可行解。

代码


#include <bits/stdc++.h>

using namespace std;

const int N=2000;//说好的1-500,开到了2000才过最后一个

vector<int> g[N];

int s[N];

int top=0;

int degree[N]={0};

int m;

//逆序最小==>在dfs的循环中,大的先想办法让他们后遍历,后入栈

//dfs在回溯后,当前点u才入栈,所以尽可能让小的点当做start

//欧拉路径 ==> 0/2个奇数点

bool cmp(int u,int v){

    return u>v;

}

void dfs(int u){

    while(!g[u].empty()){

        int v=g[u].back();

        g[u].pop_back();

        auto it=find(g[v].begin(),g[v].end(),u);

        if(it!=g[v].end()){

            g[v].erase(it);

        }

        dfs(v);

    }

    s[++top]=u;

}

int main(){

    scanf("%d",&m);

    int n=0;

    int minn=0x3f3f3f3f;

    for(int i=0;i<m;i++){

        int u,v;

        scanf("%d%d",&u,&v);

        n=max(n,max(u,v));

        minn=min(minn,min(u,v));

        g[u].push_back(v);

        g[v].push_back(u);

        degree[u]++;degree[v]++;

    }

    int start=minn;

    while(!degree[start])start++;//把起点初始化到有边的地方

    for(int i=1;i<=n;i++){

        sort(g[i].begin(),g[i].end(),cmp);

    }

    //保证了有解没必要去判断,直接找起点

    for(int i=1;i<=n;i++){

        if(degree[i]&1){

            start=i;

            break;

        }

    }

    

    dfs(start);

    

    while(top){

        printf("%d",s[top--]);

        if(top)printf("\n");

    }

    

}

POJ 1386-play on words

Description

Some of the secret doors contain a very interesting word puzzle. The team of archaeologists has to solve it to open that doors. Because there is no other way to open the doors, the puzzle is very important for us.

There is a large number of magnetic plates on every door. Every plate has one word written on it. The plates must be arranged into a sequence in such a way that every word begins with the same letter as the previous word ends. For example, the word ``acm'' can be followed by the word ``motorola''. Your task is to write a computer program that will read the list of words and determine whether it is possible to arrange all of the plates in a sequence (according to the given rule) and consequently to open the door.

Input

The input consists of T test cases. The number of them (T) is given on the first line of the input file. Each test case begins with a line containing a single integer number Nthat indicates the number of plates (1 <= N <= 100000). Then exactly Nlines follow, each containing a single word. Each word contains at least two and at most 1000 lowercase characters, that means only letters 'a' through 'z' will appear in the word. The same word may appear several times in the list.

Output

Your program has to determine whether it is possible to arrange all the plates in a sequence such that the first letter of each word is equal to the last letter of the previous word. All the plates from the list must be used, each exactly once. The words mentioned several times must be used that number of times.
If there exists such an ordering of plates, your program should print the sentence "Ordering is possible.". Otherwise, output the sentence "The door cannot be opened.".

题意翻译

输入n(n≤100000)个单词,是否可以把所有这些单词排成一个序列,使得每个单词的第一个字母可上一个单词的最后一个字母相同(例如acm,malform,mouse)。每个单词最多包含1000个小写字母。输入中可以有重复的单词。

代码:

#include <bits/stdc++.h>

using namespace std;

const int M=100010;

const int N=30;

int t;

int n,m;

//有向图的欧拉路径问题,需要记录入度和出度

int in[N];

int out[N];

//26个字母有可能有些不在图中,我们去标记下

int use[N];

//a-z看成26个点

//首字母xxxxxx尾字母

//一个单词看做是一个首字母连接到为字母的边

int p[N];

int find(int x){

    if(x!=p[x])p[x]=find(p[x]);

    return p[x];

}

void merge(int x,int y){

    int px=find(x),py=find(y);

    if(px==py)return ;

    p[px]=py;

}

int main(){

    scanf("%d",&t);

    char tmp[1001];

    while(t--){

        scanf("%d",&m);

        memset(in,0,sizeof in);

        memset(out,0,sizeof out);

        memset(use,0,sizeof use);

        memset(p,0,sizeof p);

        //连通性判断,直接使用并查集吧

        for(int i=0;i<26;i++)p[i]=i;

        while(m--){

            scanf("%s",tmp);

            int len=strlen(tmp);

            int u=tmp[0]-'a';

            int v=tmp[len-1]-'a';

            out[u]++;

            in[v]++;

            use[u]=use[v]=1;

            merge(u,v);

        }

        //判断欧拉路径

        //有向图的欧拉路径是入度和出度都相等or2个不等,一个出度大1的是start,另外一个是end

        int oddcnt=0;

        bool flag=true;

        int start=0;

        int end=0;

        for(int i=0;i<26;i++){

            if(!use[i])continue;

            if(in[i]!=out[i]){

                if(out[i]-in[i]==1)

                    start++;

                else if(out[i]-in[i]==-1)

                    end++;

                else

                    flag=false;

                oddcnt++;

            }

        }

        if(!((start==0&&end==0)||start==1&&end==1))flag=0;

        if(oddcnt!=0&&oddcnt!=2)flag=false;

        int lca=-1;

        for(int i=0;i<26;i++){

            if(!use[i])continue;

            int par=find(i);

            if(lca==-1)lca=par;

            else if(par!=lca){

                flag=false;

                break;

            }

        }

        if(!flag)printf("The door cannot be opened.");

        else printf("Ordering is possible.");

        if(t)printf("\n");

    }

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/34328.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C#特性和反射

1。特性概念理解&#xff1f; 特性&#xff08;Attribute&#xff09;是用于在【运行时】传递程序中各种元素&#xff08;比如类、属性、方法、结构、枚举、组件等&#xff09;行为信息的声明性标签。您可以通过使用特性向程序添加声明性信息。一个声明性标签是通过放置在它所…

【毕业论文格式】word分页符后的标题段前间距消失

文章目录 【问题描述】 分页符之后的段落开头&#xff0c;明明设置了标题有段前段后间距&#xff0c;但是没有显示间距&#xff1a; 【解决办法】 选中标题&#xff0c;选择边框 3. 选择段前间距&#xff0c;1~31磅的一个数 结果

操作系统-八股

进程基础&#xff1a; 进程定义&#xff1a;运行中的程序&#xff0c;有独立的内存空间和地址&#xff0c;是系统进行资源调度和分配的基本单位。 并发&#xff0c;并行 并发就是单核上面轮询&#xff0c;并行就是同时执行&#xff08;多核&#xff09;&#xff1b; 进程上下…

骑士74CMS_v3.34.0SE版uniapp全开源小程序怎么编译admin和member流程一篇文章说清楚

有粉丝一直问我骑士系统怎么编译后台和小程序目前骑士人才系统74CMS分标准版&#xff0c;创业板&#xff0c;专业版&#xff0c;其除功能不同外其配置方法完全一致有喜欢系统的也可以私信我或者找我获取 一.安装打包环境[Nodejs]这个就不用我说了吧&#xff0c;用不小于V20的版…

c语言zixue

该文主要是记录我学习中遇到的一些重点、易出问题的内容 教材p16.17 先从一个简单的例子开始吧 #include <stdio.h> //编译预处理命令 int main() //程序的主函数 {printf("To C"); //输出语句return 0; //返回语句 } #include <stdio.h>是编译预…

ollama API 本地调用

ollama API 本地调用 前提条件&#xff0c;ollama 已经启动了模型&#xff0c;查看 ollama 中的 model 名称 ollama list使用 openai 调用 from openai import OpenAI import openaiopenai.api_key ollama openai.base_url http://localhost:11434/v1/def get_completion(pro…

es6 尚硅谷 学习

1、let 1.变量不能重复声明 2.块级作用域 &#xff0c;只在块内有效 3.不存在变量提升&#xff0c;变量未声明之前不可使用 4.不影响作用域链 2、const const SCHOOL “温医”&#xff1b; 1.一定要有初始值 2.一般常量使用大写 3.常量不能赋值 4.块级作用域 5.对数组和对象…

在微信小程序或前端开发中,picker 和 select 都是用户交互中用于选择的组件,但它们在功能、设计和使用场景上有一定的区别

在微信小程序或前端开发中&#xff0c;picker 和 select 都是用户交互中用于选择的组件&#xff0c;但它们在功能、设计和使用场景上有一定的区别。 1. picker 的特点 描述&#xff1a; picker 是微信小程序中的原生组件&#xff0c;通常用于选择单项或多项值&#xff0c;如时…

C#通过API接口返回流式响应内容---分块编码方式

1、背景 上一篇文章《C#通过API接口返回流式响应内容—SSE方式》阐述了通过SSE&#xff08;Server Send Event&#xff09;方式&#xff0c;由服务器端推送数据到浏览器。本篇是通过分块编码的方式实现 2、效果 3、具体代码 3.1 API端实现 [HttpGet] public async Task Chu…

【SpringMVC】入门版

1.基本概念 1.1三层架构 三层架构也就是我们常说的b/s架构中的表现层&#xff0c;业务层和持久层,每层都各司其职&#xff0c;下面来分别讲解这三层的作用。 表现层&#xff1a; 也就是我们常说的web层。它负责接收客户端的请求&#xff0c;向客户端响应结果&#xff0c;通…

各省水资源平台 水资源遥测终端机都用什么协议

各个省水资源平台 水资源遥测终端机 的建设大部分从2012年开始启动&#xff0c;经过多年建设&#xff0c;基本都已经形成了稳定的通讯要求&#xff1b;河北瑾航科技 遥测终端机&#xff0c;兼容了大部分省市的通讯协议&#xff0c;如果需要&#xff0c;可以咨询和互相学习&…

【Android】RuntimeShader 应用

1 简介 RuntimeShader 是 Android 13&#xff08;T&#xff09;中新增的特性&#xff0c;用于逐像素渲染界面&#xff0c;它使用 AGSL&#xff08;Android Graphics Shading Language&#xff09;编写着色器代码&#xff0c;底层基于 Skia 图形渲染引擎。官方介绍详见 → Runti…

ShenNiusModularity项目源码学习(16:ShenNius.Admin.Mvc项目分析-1)

ShenNius.Admin.Mvc项目是MVC模式的启动项目&#xff0c;包括了MVC模式下所需的所有的页面、控制器类、资源、js文件等数据&#xff0c;该项目仅依赖ShenNius.Admin.API项目&#xff0c;主要使用后者的ShenniusAdminApiModule模块类及一些依赖项目中定义的辅助类等。本文学习Sh…

maven wrapper的使用

写在前面 考虑这样的场景&#xff0c;张三创建了一个maven项目使用了3.9版本&#xff0c;当李四下载下来去开发配置的却是3.6版本&#xff0c;此时李四就不得不再去配置一个3.9版本的maven&#xff0c;为了解决这个问题&#xff0c;maven引入了maven wrapper的机制&#xff08…

1、操作系统引论

一、操作系统 会使用linux系统 建议大家先学会linux的基础指令&#xff0c;可以看菜鸟教程网站进行学习。 1、各种定义 操作系统定义 管理计算机的 硬件 和软件资源&#xff0c; 能对各类作业进行调度&#xff0c;方便用户使用计算机的程序集合。操作系统运行在内核态&#xf…

如何用正则表达式爬取古诗文网中的数据(python爬虫)

一、了解正则表达式的基本内容&#xff1a; 什么是正则表达式 正则表达式&#xff08;Regular Expression&#xff0c;简称 regex&#xff09;是一种用于匹配字符串的模式。它通过特定的语法规则&#xff0c;可以高效地搜索、替换和提取文本中的特定内容。正则表达式广泛应用于…

网络空间安全(33)MSF漏洞利用

前言 Metasploit Framework&#xff08;简称MSF&#xff09;是一款功能强大的开源安全漏洞利用和测试工具&#xff0c;广泛应用于渗透测试中。MSF提供了丰富的漏洞利用模块&#xff0c;允许安全研究人员和渗透测试人员利用目标系统中的已知漏洞进行攻击。 一、漏洞利用模块&…

PBS 脚本及 运行

PBS 脚本命令的调度 PBS 脚本运行命令**如何跑&#xff1f;**准备 PBS 脚本&#xff1f; 成品 本文涉及&#xff1a; PBS 命令 Shell 命令 Python 命令 使用命令行运行作业&#xff0c;需要在 HPC 中放好 PBS 脚本。 如何写一个 PBS 脚本&#xff0c;下面以自己的 PBS 脚本为例…

Spring Cloud LoadBalancer 原理与实践

背景 当前我们的微服务架构基于Spring Cloud Alibaba体系&#xff0c;通过定制NacosRule实现了跨集群访问和灰度发布功能。但随着Spring Cloud与Nacos版本升级&#xff0c;官方已弃用Ribbon转向LoadBalancer&#xff0c;这要求我们完成以下技术升级&#xff1a; 负载均衡机制…

TMS320F28P550SJ9学习笔记13: 软件I2C_驱动AT24Cxx存储芯片

今日尝试配置软件I2C通信&#xff0c;我的目标通信芯片是AT24C64&#xff0c;相较于AT24C02这样的8位寻址&#xff0c;它是16位寻址的&#xff0c;所以有些不同 文章提供测试代码讲解、完整工程下载、测试效果图 目录 软件I2C引脚初始化&#xff1a; C内联函数改变SCL与SDA的输…