PTA图论的搜索题

目录

7-1 列出连通集

题目

输入格式:

输出格式:

输入样例:

输出样例:

AC代码

7-2 六度空间

题目

输入格式:

输出格式:

输入样例:

输出样例:

思路

AC代码

7-3 地下迷宫探索

题目

输入格式:

输出格式:

输入样例1:

输出样例1:

输入样例2:

输出样例2:

思路

AC代码

7-4 社交网络图中结点的“重要性”计算

题目

输入格式:

输出格式:

输入样例:

输出样例:

思路

AC代码

7-5 List Components

题目

Input Specification:

Output Specification:

Sample Input:

Sample Output:

思路

AC代码

7-6 排座位

题目

输入格式:

输出格式:

输入样例:

输出样例:

思路

AC代码

7-7 红色警报

题目

输入格式:

输出格式:

输入样例:

输出样例:

思路

AC代码

7-8 家庭房产

题目

输入格式:

输出格式:

输入样例:

输出样例:

思路

AC代码

7-9 肿瘤诊断

题目

输入格式:

输出格式:

输入样例:

输出样例:

思路

AC代码(BFS)

没有AC的代码(调了很久,还是2/30)。

7-10 图着色问题

题目

输入格式:

输出格式:

输入样例:

输出样例:

思路

AC代码

7-11 拯救007

输入格式:

输出格式:

输入样例 1:

输出样例 1:

输入样例 2:

输出样例 2:

思路

AC代码


7-1 列出连通集

题目

分数 25

作者 陈越

单位 浙江大学

给定一个有N个顶点和E条边的无向图,请用DFS和BFS分别列出其所有的连通集。假设顶点从0到N−1编号。进行搜索时,假设我们总是从编号最小的顶点出发,按编号递增的顺序访问邻接点。

输入格式:

输入第1行给出2个整数N(0<N≤10)和E,分别是图的顶点数和边数。随后E行,每行给出一条边的两个端点。每行中的数字之间用1空格分隔。

输出格式:

按照"{ v1​ v2​ ... vk​ }"的格式,每行输出一个连通集。先输出DFS的结果,再输出BFS的结果。

输入样例:

8 6
0 7
0 1
2 0
4 1
2 4
3 5

输出样例:

{ 0 1 4 2 7 }
{ 3 5 }
{ 6 }
{ 0 1 2 7 4 }
{ 3 5 }
{ 6 }

代码长度限制

16 KB

时间限制

400 ms

内存限制

64 MB

AC代码

#include<iostream>
#include<vector>
#include<cstring>
#include<queue>
using namespace std;
int mat[11][11];
bool visited[12];
vector<int> v;
void dfs(int cur,int n)
{
    visited[cur]=true;
    v.push_back(cur);
    for(int i=0;i<n;i++)
    {
        if(visited[i]==true||i==cur)
            continue;
        if(mat[cur][i]==1)
            dfs(i,n);
    }
}
void bfs(int cur,int n)
{
    queue<int> Q;
    Q.push(cur);
    visited[cur]=true;
    v.push_back(cur);//v存放cur所在的连通集
    while(!Q.empty())
    {
        int k=Q.size();
        for(int i=0;i<k;i++)
        {
            //取队头元素的所有直接联通点
            for(int j=0;j<n;j++)
            {
                if(visited[j]==true||Q.front()==j)
                    continue;
                if(mat[Q.front()][j]==1)
                {
                    Q.push(j);
                    visited[j]=true;
                    v.push_back(j);
                }
            }
            Q.pop();
        }
    }
}
int main()
{
    int n,e;
    cin>>n>>e;
    for(int i=0;i<e;i++)
    {
        int a,b;
        cin>>a>>b;
        mat[a][b]=mat[b][a]=1;
    }
    memset(visited,false,sizeof(visited)/sizeof(bool));
    //dfs
    for(int i=0;i<n;i++)
    {
        v.resize(0);
        if(visited[i]==false)
            dfs(i,n);
        for(int j=0;j<v.size();j++)
        {
            if(j==0)
                cout<<"{ ";
            cout<<v[j]<<" ";
            if(j==v.size()-1)
                cout<<"}\n";
        }
    }
    //bfs
    memset(visited,false,sizeof(visited)/sizeof(bool));
    for(int i=0;i<n;i++)
    {
        v.resize(0);
        if(visited[i]==false)
            bfs(i,n);
        for(int j=0;j<v.size();j++)
        {
            if(j==0)
                cout<<"{ ";
            cout<<v[j]<<" ";
            if(j==v.size()-1)
                cout<<"}\n";
        }
    }
}

7-2 六度空间

题目

分数 30

作者 DS课程组

单位 浙江大学

“六度空间”理论又称作“六度分隔(Six Degrees of Separation)”理论。这个理论可以通俗地阐述为:“你和任何一个陌生人之间所间隔的人不会超过六个,也就是说,最多通过五个人你就能够认识任何一个陌生人。”如图1所示。


图1 六度空间示意图

“六度空间”理论虽然得到广泛的认同,并且正在得到越来越多的应用。但是数十年来,试图验证这个理论始终是许多社会学家努力追求的目标。然而由于历史的原因,这样的研究具有太大的局限性和困难。随着当代人的联络主要依赖于电话、短信、微信以及因特网上即时通信等工具,能够体现社交网络关系的一手数据已经逐渐使得“六度空间”理论的验证成为可能。

假如给你一个社交网络图,请你对每个节点计算符合“六度空间”理论的结点占结点总数的百分比。

输入格式:

输入第1行给出两个正整数,分别表示社交网络图的结点数N(1<N≤103,表示人数)、边数M(≤33×N,表示社交关系数)。随后的M行对应M条边,每行给出一对正整数,分别是该条边直接连通的两个结点的编号(节点从1到N编号)。

输出格式:

对每个结点输出与该结点距离不超过6的结点数占结点总数的百分比,精确到小数点后2位。每个结节点输出一行,格式为“结点编号:(空格)百分比%”。

输入样例:

10 9
1 2
2 3
3 4
4 5
5 6
6 7
7 8
8 9
9 10

输出样例:

1: 70.00%
2: 80.00%
3: 90.00%
4: 100.00%
5: 100.00%
6: 100.00%
7: 100.00%
8: 90.00%
9: 80.00%
10: 70.00%

代码长度限制

16 KB

时间限制

2500 ms

内存限制

64 MB

思路

广度优先搜索,通过几层的搜索能找到另一人就是两个人之间的间隔。

AC代码

这题是刚学数据结构时写的,里面有一些复杂的结构。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#define MVNum 1000
#define Maxint 32767
using namespace std;
bool visited[MVNum];
typedef int VerTexType;
typedef int ArcType;

//邻接表
typedef struct ArcNode {//边 
	int adjvex;  //边所指向顶点的位置 
	struct ArcNode* nextarc; //下一个边 
}ArcNode;
typedef struct VNode {//顶点 
	VerTexType date;
	ArcNode* firstarc;
}VNode, AdjList[MVNum];
typedef struct {  //邻接表 
	AdjList vertices;
	int vexnum, arcnum;
}ALGraph;

void CreateUDG(ALGraph& G)
{//创建无向图的邻接表 
	cin >> G.vexnum >> G.arcnum;
	//顶点赋初值 
	for (int i = 0; i < G.vexnum; i++)
	{
		G.vertices[i].date = i + 1;
		G.vertices[i].firstarc = NULL;
	}
	for (int k = 0; k < G.arcnum; k++)
	{
		int i, j;
		cin >> i >> j;
		i--;
		j--;
		ArcNode* p1, * p2;
		//i邻接一条边j 
		p1 = new ArcNode;
		p1->adjvex = j;
		p1->nextarc = G.vertices[i].firstarc;
		G.vertices[i].firstarc = p1;
		//j邻接一条边i
		p2 = new ArcNode;
		p2->adjvex = i;
		p2->nextarc = G.vertices[j].firstarc;
		G.vertices[j].firstarc = p2;
	}
}
double BFS_AL(ALGraph& G, int v)
{//从下标为V的点开始广度优先搜索,对邻接表 
//	cout << "从下标" << v << "开始查找:";
	int friends = 0;
	int step = 0;//节点之间的距离 
	memset(visited, false, sizeof(bool) * G.vexnum);
	queue<VNode>Q;  //队列的元素是邻接表的点,不是邻接表边
	Q.push(G.vertices[v]);
	visited[v] = true;
	while (!Q.empty() && step < 6)
	{
		step++;
//		cout << "\n第" << step << "步访问的下标:";
		//取队里的所有点,并将这些元素的未标记的邻接点放进队列
		int n = Q.size();
		for (int i = 0; i < n; i++)
		{
			VNode p = Q.front();
			Q.pop();
			//找出队元素所有未被访问的邻接点 (即找某个人的所有朋友)
			ArcNode* q = p.firstarc;
			while (q != NULL)
			{
				if (visited[q->adjvex] == false)
				{
					visited[q->adjvex] = true;
					Q.push(G.vertices[q->adjvex]);
				}
				q = q->nextarc;
			}
		}
	}//while
	//计算比例 ,六步之内找到的朋友(包括自己)/总人数 
	for (int i = 0; i < G.vexnum; i++)
		if (visited[i] == true) friends++;
//	cout << "vexnum=" << G.vexnum << "  " << "friends=" << friends << "  ";
	return 1.0 * friends / G.vexnum;
}

int main()
{
	ALGraph G;
	CreateUDG(G);
	for (int i = 0; i < G.vexnum; i++)
	{
		double a = 100 * BFS_AL(G, i);
		printf("%d: %.2lf%%\n", i + 1, a);
	}
	return 0;
}

7-3 地下迷宫探索

题目

分数 30

作者 DS课程组

单位 浙江大学

地道战是在抗日战争时期,在华北平原上抗日军民利用地道打击日本侵略者的作战方式。地道网是房连房、街连街、村连村的地下工事,如下图所示。

我们在回顾前辈们艰苦卓绝的战争生活的同时,真心钦佩他们的聪明才智。在现在和平发展的年代,对多数人来说,探索地下通道或许只是一种娱乐或者益智的游戏。本实验案例以探索地下通道迷宫作为内容。

假设有一个地下通道迷宫,它的通道都是直的,而通道所有交叉点(包括通道的端点)上都有一盏灯和一个开关。请问你如何从某个起点开始在迷宫中点亮所有的灯并回到起点?

输入格式:

输入第一行给出三个正整数,分别表示地下迷宫的节点数N(1<N≤1000,表示通道所有交叉点和端点)、边数M(≤3000,表示通道数)和探索起始节点编号S(节点从1到N编号)。随后的M行对应M条边(通道),每行给出一对正整数,分别是该条边直接连通的两个节点的编号。

输出格式:

若可以点亮所有节点的灯,则输出从S开始并以S结束的包含所有节点的序列,序列中相邻的节点一定有边(通道);否则虽然不能点亮所有节点的灯,但还是输出点亮部分灯的节点序列,最后输出0,此时表示迷宫不是连通图。

由于深度优先遍历的节点序列是不唯一的,为了使得输出具有唯一的结果,我们约定以节点小编号优先的次序访问(点灯)。在点亮所有可以点亮的灯后,以原路返回的方式回到起点。

输入样例1:

6 8 1
1 2
2 3
3 4
4 5
5 6
6 4
3 6
1 5

输出样例1:

1 2 3 4 5 6 5 4 3 2 1

输入样例2:

6 6 6
1 2
1 3
2 3
5 4
6 5
6 4

输出样例2:

6 4 5 4 6 0

代码长度限制

16 KB

时间限制

400 ms

内存限制

64 MB

思路

深度优先搜索。但是这题并不是说每个节点只遍历一次,而是说在遍历完所有的节点的过程中,访问某个节点和访问完这个节点回溯时都要打印一次。

AC代码

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
const int SIZE = 1005;
int N, M, S;
int cnt = 0; //记录输出的数量,防止多输出空格
vector<vector<int>> arc;
vector<int> path;
int visited[SIZE];
void inif()
{
    arc.resize(N + 1);
    for (int i = 0; i < M; i++)
    {
        int arc1, arc2;
        cin >> arc1 >> arc2;
        arc[arc1].push_back(arc2);
        arc[arc2].push_back(arc1);
    }
    //排序,优先访问序列小的节点
    for (int i = 1; i <= N; i++)
    {
        sort(arc[i].begin(), arc[i].end());
    }
}
void dfs(int i)
{
    visited[i] = 1;
    cnt++;
    //点灯时输出一次
    if (cnt == 1) cout << i;
    else cout << " " << i;
    for (int j = 0; j < arc[i].size(); j++)
    {
        if (visited[arc[i][j]] == 0)
        {
            dfs(arc[i][j]);
            //点完相邻的灯后输出一次
            cout << " " << i;
        }
    }
}
int main()
{
    cin >> N >> M >> S;
    inif();
    dfs(S);
    if(cnt!=N) cout<<" 0";
}

7-4 社交网络图中结点的“重要性”计算

题目

分数 30

作者 DS课程组

单位 浙江大学

在社交网络中,个人或单位(结点)之间通过某些关系(边)联系起来。他们受到这些关系的影响,这种影响可以理解为网络中相互连接的结点之间蔓延的一种相互作用,可以增强也可以减弱。而结点根据其所处的位置不同,其在网络中体现的重要性也不尽相同。

“紧密度中心性”是用来衡量一个结点到达其它结点的“快慢”的指标,即一个有较高中心性的结点比有较低中心性的结点能够更快地(平均意义下)到达网络中的其它结点,因而在该网络的传播过程中有更重要的价值。在有N个结点的网络中,结点vi​的“紧密度中心性”Cc(vi​)数学上定义为vi​到其余所有结点vj​ (j=i) 的最短距离d(vi​,vj​)的平均值的倒数:

对于非连通图,所有结点的紧密度中心性都是0。

给定一个无权的无向图以及其中的一组结点,计算这组结点中每个结点的紧密度中心性。

输入格式:

输入第一行给出两个正整数N和M,其中N(≤104)是图中结点个数,顺便假设结点从1到N编号;M(≤105)是边的条数。随后的M行中,每行给出一条边的信息,即该边连接的两个结点编号,中间用空格分隔。最后一行给出需要计算紧密度中心性的这组结点的个数K(≤100)以及K个结点编号,用空格分隔。

输出格式:

按照Cc(i)=x.xx的格式输出K个给定结点的紧密度中心性,每个输出占一行,结果保留到小数点后2位。

输入样例:

9 14
1 2
1 3
1 4
2 3
3 4
4 5
4 6
5 6
5 7
5 8
6 7
6 8
7 8
7 9
3 3 4 9

输出样例:

Cc(3)=0.47
Cc(4)=0.62
Cc(9)=0.35

代码长度限制

16 KB

时间限制

20000 ms

内存限制

64 MB

思路

用广度优先搜索计算某个点到其他点的距离。其间用一个数记录联通点的数量,若联通点的数量不等于N,就全输出0。

AC代码

#include<iostream>
#include<vector>
#include<queue>
using namespace std;
const int MAXSIZE=10005;
int N,M,K;
vector<vector<int>> f;   //用于记忆化
vector<vector<int>> arcs; //邻接表
int visited[MAXSIZE];
bool flag=true;  //标志是否连通
int cnt=0;      //联通点的数量
void inif()
{
    cin>>N>>M;
    arcs.resize(N+1);
    for(int i=0;i<M;i++)
    {
        int arc1,arc2;
        cin>>arc1>>arc2;
        arcs[arc1].push_back(arc2);
        arcs[arc2].push_back(arc1);
    }
}
void MEMSET(){for(int i=1;i<=N;i++) visited[i]=0;}
long long bfs(int x)
{
    if(!flag) return -1;
    MEMSET();
    long long sum=0;
    int length=0;//点x到某个点的长度
    queue<int> q;
    q.push(x);
    visited[x]=1;
    cnt=1;
    while(!q.empty()){
        int size=q.size();
        ++length;
        for(int i=0;i<size;i++){
            int cur=q.front();
            q.pop();
            for(auto arc:arcs[cur]){
                if(visited[arc]==0){
                    q.push(arc);
                    ++cnt;
                    visited[arc]=1;
                    sum+=length;
                }
            }
        }
    }
    if(cnt!=N){
        flag=false;
        return -1;
    }
    return sum;
}
void slove()
{
    cin>>K;
    for(int i=0;i<K;i++){
        if(i!=0) cout<<endl;
        int x;
        cin>>x;
        if(!flag){
            cout<<"Cc("<<x<<")=0.00";
            continue;
        }
        double aver=1.0*(N-1)/bfs(x);
        if(!flag){
            cout<<"Cc("<<x<<")=0.00";
            continue;
        }
        printf("Cc(%d)=%.2lf",x,aver);
    }
}
int main()
{
    inif();
    slove();
}

7-5 List Components

题目

分数 25

作者 陈越

单位 浙江大学

For a given undirected graph with N vertices and E edges, please list all the connected components by both DFS (Depth First Search) and BFS (Breadth First Search). Assume that all the vertices are numbered from 0 to N-1. While searching, assume that we always start from the vertex with the smallest index, and visit its adjacent vertices in ascending order of their indices.

Input Specification:

Each input file contains one test case. For each case, the first line gives two integers N (0<N≤10) and E, which are the number of vertices and the number of edges, respectively. Then E lines follow, each described an edge by giving the two ends. All the numbers in a line are separated by a space.

Output Specification:

For each test case, print in each line a connected component in the format { v1​ v2​ ... vk​ }. First print the result obtained by DFS, then by BFS.

Sample Input:

8 6
0 7
0 1
2 0
4 1
2 4
3 5

Sample Output:

{ 0 1 4 2 7 }
{ 3 5 }
{ 6 }
{ 0 1 2 7 4 }
{ 3 5 }
{ 6 }

代码长度限制

16 KB

时间限制

400 ms

内存限制

64 MB

思路

这是一个英文题,稍微阅读一下然后和7-1的输入输出对比一下会发现,这题就是7-1的英文版。

AC代码

#include<iostream>
#include<queue>
using namespace std;
int f[15][15];
int visited[15];
int N, E;
vector<int> g;
int flag = false;
void dfs(int i)
{
    for (int j = 0; j < N; j++) {
        if (f[i][j] == 1 && visited[j] == 0) {
            g.push_back(j);
            visited[j] = 1;
            dfs(j);
        }
    }
}
void bfs(int i)
{
    queue<int> q;
    q.push(i);
    g.push_back(i);
    visited[i] = 1;
    while (!q.empty()) {
        int cur = q.front();
        q.pop();
        for (int j = 0; j < N; j++) {
            if (f[cur][j] == 1 && visited[j] == 0) {
                visited[j] = 1;
                g.push_back(j);
                q.push(j);
            }
        }
    }
}
int main()
{
    cin >> N >> E;
    for (int i = 0; i < E; i++) {
        int x, y;
        cin >> x >> y;
        f[x][y] = f[y][x] = 1;
    }

    for (int i = 0; i < N; i++) {
        if (visited[i] == 0) {
            visited[i] = 1;
            g.resize(0);
            g.push_back(i);
            dfs(i);
            if (flag == true) cout << endl;
            flag = true;
            cout << "{ ";
            for (int j = 0; j < g.size(); j++) {
                cout << g[j] << " ";
            }
            cout << "}";
        }
    }

    for (int i = 0; i < N; i++) visited[i] = 0;
    for (int i = 0; i < N; i++) {
        if (visited[i] == 0) {
            g.resize(0);
            bfs(i);
            if (flag == true) cout << endl;
            flag = true;
            cout << "{ ";
            for (int j = 0; j < g.size(); j++) {
                cout << g[j] << " ";
            }
            cout << "}";
        }
    }
}

7-6 排座位

题目

分数 25

作者 陈越

单位 浙江大学

布置宴席最微妙的事情,就是给前来参宴的各位宾客安排座位。无论如何,总不能把两个死对头排到同一张宴会桌旁!这个艰巨任务现在就交给你,对任何一对客人,请编写程序告诉主人他们是否能被安排同席。

输入格式:

输入第一行给出3个正整数:N(≤100),即前来参宴的宾客总人数,则这些人从1到N编号;M为已知两两宾客之间的关系数;K为查询的条数。随后M行,每行给出一对宾客之间的关系,格式为:宾客1 宾客2 关系,其中关系为1表示是朋友,-1表示是死对头。注意两个人不可能既是朋友又是敌人。最后K行,每行给出一对需要查询的宾客编号。

这里假设朋友的朋友也是朋友。但敌人的敌人并不一定就是朋友,朋友的敌人也不一定是敌人。只有单纯直接的敌对关系才是绝对不能同席的。

输出格式:

对每个查询输出一行结果:如果两位宾客之间是朋友,且没有敌对关系,则输出No problem;如果他们之间并不是朋友,但也不敌对,则输出OK;如果他们之间有敌对,然而也有共同的朋友,则输出OK but...;如果他们之间只有敌对关系,则输出No way

输入样例:

7 8 4
5 6 1
2 7 -1
1 3 1
3 4 1
6 7 -1
1 2 1
1 4 1
2 3 -1
3 4
5 7
2 3
7 2

输出样例:

No problem
OK
OK but...
No way

代码长度限制

16 KB

时间限制

200 ms

内存限制

64 MB

思路

并查集判断两个人是否是朋友(的朋友的朋友的朋友……)。

AC代码

#include<iostream>
using namespace std;
const int MAXSIZE = 105;
int N, M, K;
int relation[MAXSIZE][MAXSIZE];
int fa[MAXSIZE * MAXSIZE];
int find(int x)
{
    int r = x;
    while (fa[r] != r)
    {
        fa[r] = fa[fa[r]];
        r = fa[r];
    }
    return r;
}
void merge(int x, int y)
{
    int fx = find(x);
    int fy = find(y);
    if (fx > fy) {
        fa[fy] = fx;
    }
    else {
        fa[fx] = fy;
    }
}
int node(int i, int j) { return N * (i - 1) + j; }
void inif()
{
    cin >> N >> M >> K;
    for (int i = 1; i <= N; i++) {
        fa[i] = i;
        for (int j = 1; j <= N; j++) {
            relation[i][j] = 0;
        }
    }
    for (int i = 0; i < M; i++)
    {
        int x, y, c;
        cin >> x >> y >> c;
        relation[x][y] = relation[y][x] = c;
        if (c == 1) merge(x, y);
    }
}
void slove()
{
    for (int i = 0; i < K; i++)
    {
        if (i != 0) cout << endl;
        int x, y;
        cin >> x >> y;
        bool flag = (find(x) == find(y));
        if (flag && relation[x][y] != -1) cout << "No problem";
        else if (!flag && relation[x][y] != -1) cout << "OK";
        else if (flag && relation[x][y] == -1) cout << "OK but...";
        else cout << "No way";
    }
}
int main()
{
    inif();
    slove();
}

7-7 红色警报

题目

分数 25

作者 陈越

单位 浙江大学

战争中保持各个城市间的连通性非常重要。本题要求你编写一个报警程序,当失去一个城市导致国家被分裂为多个无法连通的区域时,就发出红色警报。注意:若该国本来就不完全连通,是分裂的k个区域,而失去一个城市并不改变其他城市之间的连通性,则不要发出警报。

输入格式:

输入在第一行给出两个整数N(0 < N ≤ 500)和M(≤ 5000),分别为城市个数(于是默认城市从0到N-1编号)和连接两城市的通路条数。随后M行,每行给出一条通路所连接的两个城市的编号,其间以1个空格分隔。在城市信息之后给出被攻占的信息,即一个正整数K和随后的K个被攻占的城市的编号。

注意:输入保证给出的被攻占的城市编号都是合法的且无重复,但并不保证给出的通路没有重复。

输出格式:

对每个被攻占的城市,如果它会改变整个国家的连通性,则输出Red Alert: City k is lost!,其中k是该城市的编号;否则只输出City k is lost.即可。如果该国失去了最后一个城市,则增加一行输出Game Over.

输入样例:

5 4
0 1
1 3
3 0
0 4
5
1 2 0 4 3

输出样例:

City 1 is lost.
City 2 is lost.
Red Alert: City 0 is lost!
City 4 is lost.
City 3 is lost.
Game Over.

代码长度限制

16 KB

时间限制

400 ms

内存限制

64 MB

思路

构建好图后先记录一次连通集个数。随后每删除一个点就更新一次连通集个数。若连通集个数没变或只是减了一个,则说明没有改变整个国家的连通性。

AC代码

#include<iostream>
#include<vector>
#include<queue>
using namespace std;
const int MAXSIZE = 505;
int N, M, K;
vector<vector<int>> g;
int book[MAXSIZE];
int lost[MAXSIZE];//==1表示已经失去
int unionCount = 0;
int func()
{
    int sum = 0;
    for (int i = 0; i < N; i++) book[i] = 0;
    for (int i = 0; i < N; i++) {
        if (book[i] == 1 || lost[i] == 1) continue;
        sum++;
        queue<int> q;
        q.push(i);
        while (!q.empty()) {
            int cur = q.front();
            q.pop();
            for (int j = 0; j < g[cur].size(); j++) {
                int node = g[cur][j];
                if (lost[node] == 1 || book[node] == 1) continue;
                q.push(node);
                book[node] = 1;
            }
        }
    }
    return sum;
}
void slove()
{
    cin >> K;
    int aim;
    for (int i = 0; i < K; i++) {
        cin >> aim;
        if (i != 0) cout << endl;
        lost[aim] = 1;
        int cnt = func();
        if (cnt == unionCount || cnt == unionCount - 1) {
            cout << "City " << aim << " is lost.";
        }
        else {
            cout << "Red Alert: City " << aim << " is lost!";
        }
        unionCount = cnt;//更新
        if (i == N - 1) {
            cout << "\nGame Over.";
        }
    }
}
int main()
{
    cin >> N >> M;
    g.resize(N);
    for (int i = 0; i < M; i++) {
        int x, y;
        cin >> x >> y;
        g[x].push_back(y);
        g[y].push_back(x);
    }
    unionCount = func();
    slove();
    //cout << unionCount;
}

7-8 家庭房产

题目

分数 25

作者 陈越

单位 浙江大学

给定每个人的家庭成员和其自己名下的房产,请你统计出每个家庭的人口数、人均房产面积及房产套数。

输入格式:

输入第一行给出一个正整数N(≤1000),随后N行,每行按下列格式给出一个人的房产:

编号 父 母 k 孩子1 ... 孩子k 房产套数 总面积

其中编号是每个人独有的一个4位数的编号;分别是该编号对应的这个人的父母的编号(如果已经过世,则显示-1);k(0≤k≤5)是该人的子女的个数;孩子i是其子女的编号。

输出格式:

首先在第一行输出家庭个数(所有有亲属关系的人都属于同一个家庭)。随后按下列格式输出每个家庭的信息:

家庭成员的最小编号 家庭人口数 人均房产套数 人均房产面积

其中人均值要求保留小数点后3位。家庭信息首先按人均面积降序输出,若有并列,则按成员编号的升序输出。

输入样例:

10
6666 5551 5552 1 7777 1 100
1234 5678 9012 1 0002 2 300
8888 -1 -1 0 1 1000
2468 0001 0004 1 2222 1 500
7777 6666 -1 0 2 300
3721 -1 -1 1 2333 2 150
9012 -1 -1 3 1236 1235 1234 1 100
1235 5678 9012 0 1 50
2222 1236 2468 2 6661 6662 1 300
2333 -1 3721 3 6661 6662 6663 1 100

输出样例:

3
8888 1 1.000 1000.000
0001 15 0.600 100.000
5551 4 0.750 100.000

代码长度限制

16 KB

时间限制

400 ms

内存限制

64 MB

思路

这题要是一开始就告诉你出现过的人有几个并且所有人的编号都为1-N,那么这题就不难。难点就是所有人的编号是离散的,就要一些特殊处理。

我们用并查集来判断家庭的个数,每次合并两个人的时候,将编号大的指向编号小的。这样统计面积的时候就只需要将每个点的面积属性加到father数组的根当中即可。最后将家庭按照面积降序、最小编号升序的方式排序,然后输出。

AC代码

#include<bits/stdc++.h>
using namespace std;
const int MAXSIZE=1e5+5;
int N;
int family=0;
int fa[MAXSIZE];
bool visited[MAXSIZE];
struct new_person{
    int id,fid,mid,num,area,k;
    int child[6];
} g[1005];
struct _ans{
    int minid=0,people=0;
    double num=0,area=0;
    bool have=false;
} ans[MAXSIZE];
bool cmp(_ans a,_ans b)
{
    if(a.area==b.area)
        return a.minid<b.minid;
    return a.area>b.area;
}
int find(int x)
{
    int r=x;
    while(fa[r]!=r) r=fa[r];
    return r;
}
void merge(int x,int y)
{
    int fx=find(x);
    int fy=find(y);
    if(fx<fy) fa[fy]=fx;
    else if(fx>fy) fa[fx]=fy;
}
int main()
{
    cin>>N;
    for(int i=0;i<MAXSIZE;i++) fa[i]=i;
    //处理输入数据
    for(int i=0;i<N;i++){
        cin>>g[i].id>>g[i].fid>>g[i].mid>>g[i].k;
        visited[g[i].id]=true;
        if(g[i].fid!=-1){
            visited[g[i].fid]=true;
            merge(g[i].id,g[i].fid);
        }
        if(g[i].mid!=-1){
            visited[g[i].mid]=true;
            merge(g[i].id,g[i].mid);
        }
        for(int j=0;j<g[i].k;j++){
            cin>>g[i].child[j];
            visited[g[i].child[j]]=true;
            merge(g[i].id,g[i].child[j]);
        }
        cin>>g[i].num>>g[i].area;
    }
    //统计房产和每个家庭最小id
    for(int i=0;i<N;i++){
        int j=find(g[i].id);
        ans[j].minid=j;
        ans[j].num+=g[i].num;  //房产个数
        ans[j].area+=g[i].area;  //房产面积 
        ans[j].have=true;
    }
    //统计每个家庭人数和家庭个数
    for(int i=0;i<10000;i++){
        if(visited[i]) ans[find(i)].people++;
        if(ans[i].have) family++;
    }
    //将房产个数和房产面积转换为平均值
    for(int i=0;i<10000;i++){
        if(ans[i].have){
            ans[i].num=(double)(1.0*ans[i].num/ans[i].people);
            ans[i].area=(double)(1.0*ans[i].area/ans[i].people);
        }
    }
    //排序并输出
    sort(ans,ans+10000,cmp);
    cout<<family;
    for(int i=0;i<family;i++){
        printf("\n%04d %d %.3lf %.3lf",ans[i].minid,ans[i].people,ans[i].num,ans[i].area);
    }
}

7-9 肿瘤诊断

题目

分数 30

作者 陈越

单位 浙江大学

在诊断肿瘤疾病时,计算肿瘤体积是很重要的一环。给定病灶扫描切片中标注出的疑似肿瘤区域,请你计算肿瘤的体积。

输入格式:

输入第一行给出4个正整数:M、N、L、T,其中M和N是每张切片的尺寸(即每张切片是一个M×N的像素矩阵。最大分辨率是1286×128);L(≤60)是切片的张数;T是一个整数阈值(若疑似肿瘤的连通体体积小于T,则该小块忽略不计)。

最后给出L张切片。每张用一个由0和1组成的M×N的矩阵表示,其中1表示疑似肿瘤的像素,0表示正常像素。由于切片厚度可以认为是一个常数,于是我们只要数连通体中1的个数就可以得到体积了。麻烦的是,可能存在多个肿瘤,这时我们只统计那些体积不小于T的。两个像素被认为是“连通的”,如果它们有一个共同的切面,如下图所示,所有6个红色的像素都与蓝色的像素连通。

输出格式:

在一行中输出肿瘤的总体积。

输入样例:

3 4 5 2
1 1 1 1
1 1 1 1
1 1 1 1
0 0 1 1
0 0 1 1
0 0 1 1
1 0 1 1
0 1 0 0
0 0 0 0
1 0 1 1
0 0 0 0
0 0 0 0
0 0 0 1
0 0 0 1
1 0 0 0

输出样例:

26

代码长度限制

16 KB

时间限制

1000 ms

内存限制

64 MB

思路

刚开始看不懂题目什么意思,后面发现,就是一个图结构,要我们判断所有体积大于T的连通块。

但是以往的邻接矩阵都是二维的,有四个方向。这次是三维的,有六个方向。

AC代码(BFS)

#include<iostream>
#include<queue>
using namespace std;
int M, N, L, T;
struct Node {
	int x, y, z;
};
int dx[6] = { 1,-1,0,0,0,0 };
int dy[6] = { 0,0,1,-1,0,0 };
int dz[6] = { 0,0,0,0,1,-1 };
int f[1300][130][70];
int book[1300][130][70];
int sum = 0;
int bfs(int x, int y, int z)
{
	int ans = 1;
	queue<Node> q;
	q.push({ x,y,z });
	while (!q.empty()) {
		Node node = q.front();
		q.pop();
		//遍历六个方向
		for (int i = 0; i < 6; i++) {
			int new_x = node.x + dx[i];
			int new_y = node.y + dy[i];
			int new_z = node.z + dz[i];
			if (new_x < 0 || new_x >= M || new_y < 0 || new_y >= N || new_z < 0 || new_z >= L || book[new_x][new_y][new_z] == 1 || f[new_x][new_y][new_z] == 0)
				continue;
			ans++;
			book[new_x][new_y][new_z] = 1;
			q.push({ new_x,new_y,new_z });
		}
	}
	if (ans >= T) return ans;
	else return 0;
}
int main()
{
	cin >> M >> N >> L >> T;
	for (int i = 0; i < L; i++)
		for (int j = 0; j < M; j++)
			for (int k = 0; k < N; k++)
				cin >> f[j][k][i];
	for (int i = 0; i < L; i++)
		for (int j = 0; j < M; j++)
			for (int k = 0; k < N; k++)
				if (f[j][k][i] == 1 && book[j][k][i] == 0) {
					book[j][k][i] = 1;
					sum += bfs(j, k, i);
				}
	cout << sum << endl;
	return 0;
}

没有AC的代码(调了很久,还是2/30)。

只有一个点2分,其他点都是运行超时或者内存超限。将BFS的倒数第七句的[tz][tz][ty]改成[tz][tx][ty]还是只有6分。又发现错误的大佬可以指正一下。

#include<iostream>
#include<queue>
#include<vector>
using namespace std;
int M, N, L, T;
int f[61][1287][130];
bool visited[61][1287][130];
//上下前后左右六个方向
int dx[6] = { 0,0,-1,1,0,0 };
int dy[6] = { 0,0,0,0,-1,1 };
int dz[6] = { -1,1,0,0,0,0 };
struct coord {
    int x, y, z;
};
int bfs(int x_, int y_, int z_)
{
    int ans = 1;
    queue<coord> q;//{z,x,y}
    coord p = { x_,y_,z_ };
    q.push(p);
    visited[z_][x_][y_] = 1;
    while (!q.empty()) {
        coord cur = q.front();
        q.pop();
        int x = cur.x;
        int y = cur.y;
        int z = cur.z;
        for (int i = 0; i < 6; i++) {
            int tx = x + dx[i];
            int ty = y + dy[i];
            int tz = z + dz[i];
            if (tx >= 0 && tx < M && ty >= 0 && ty < N && tz >= 0 && tz < L && visited[tz][tx][ty] == false && f[tz][tx][ty] == 1) {
                coord adj = { tx,ty,tz };
                q.push(adj);
                visited[tz][tz][ty] = 1;
                ans++;
            }
        }
    }
    return ans;
}
int main()
{
    cin >> M >> N >> L >> T;
    for (int i = 0; i < L; i++) {
        for (int j = 0; j < M; j++) {
            for (int k = 0; k < N; k++) {
                cin >> f[i][j][k];
            }
        }
    }
    int sum = 0;
    /*
    int sum1 = sizeof(f) / sizeof(int);
    int sum2 = sizeof(visited) / sizeof(int);
    cout << sum1 << endl << sum2 << endl;
    */
    for (int i = 0; i < L; i++) {
        for (int j = 0; j < M; j++) {
            for (int k = 0; k < N; k++) {
                if (visited[i][j][k] == 1 || f[i][j][k] == 0) continue;
                int v = bfs(i, j, k);
                sum += (v >= T ? v : 0);
            }
        }
    }
    cout << sum;
}

7-10 图着色问题

题目

分数 25

作者 陈越

单位 浙江大学

图着色问题是一个著名的NP完全问题。给定无向图G=(V,E),问可否用K种颜色为V中的每一个顶点分配一种颜色,使得不会有两个相邻顶点具有同一种颜色?

但本题并不是要你解决这个着色问题,而是对给定的一种颜色分配,请你判断这是否是图着色问题的一个解。

输入格式:

输入在第一行给出3个整数V(0<V≤500)、E(≥0)和K(0<K≤V),分别是无向图的顶点数、边数、以及颜色数。顶点和颜色都从1到V编号。随后E行,每行给出一条边的两个端点的编号。在图的信息给出之后,给出了一个正整数N(≤20),是待检查的颜色分配方案的个数。随后N行,每行顺次给出V个顶点的颜色(第i个数字表示第i个顶点的颜色),数字间以空格分隔。题目保证给定的无向图是合法的(即不存在自回路和重边)。

输出格式:

对每种颜色分配方案,如果是图着色问题的一个解则输出Yes,否则输出No,每句占一行。

输入样例:

6 8 3
2 1
1 3
4 6
2 5
2 4
5 4
5 6
3 6
4
1 2 3 3 1 2
4 5 6 6 4 5
1 2 3 4 5 6
2 3 4 2 3 4

输出样例:

Yes
Yes
No
No

代码长度限制

16 KB

时间限制

300 ms

内存限制

64 MB

思路

以此判断每个点是否有颜色相同的相邻点。甚至不用搜索。

关键点是每一个方案颜色只能有K种(刚好K种)。

AC代码

//只用k种颜色,不多不少
#include<iostream>
#include<vector>
#include<map>
#include<queue>
using namespace std;
int V,E,K;
vector<vector<int>> g;
int color[502];
int main()
{
    cin>>V>>E>>K;
    g.resize(V+1);
    for(int i=0;i<E;i++){
        int x,y;
        cin>>x>>y;
        g[x].emplace_back(y);
        g[y].emplace_back(x);
    }
    int n;
    cin>>n;
    while(n--){
        map<int,int> mp;
        for(int i=1;i<=V;i++){
            cin>>color[i];
            mp[color[i]]++;
        }
        int color_cnt=mp.size();
        if(color_cnt!=K){
            cout<<"No\n";
            continue;
        }
        bool flag=true;
        for(int i=1;i<=V;i++){
            for(int j=0;j<g[i].size();j++){
                if(color[i]==color[g[i][j]]){
                    flag=false;
                    goto loop;
                }
            }
        }
        loop:;
        if(flag) cout<<"Yes\n";
        else cout<<"No\n";
    }
}

7-11 拯救007

分数 25

作者 陈越

单位 浙江大学

在老电影“007之生死关头”(Live and Let Die)中有一个情节,007被毒贩抓到一个鳄鱼池中心的小岛上,他用了一种极为大胆的方法逃脱 —— 直接踩着池子里一系列鳄鱼的大脑袋跳上岸去!(据说当年替身演员被最后一条鳄鱼咬住了脚,幸好穿的是特别加厚的靴子才逃过一劫。)

设鳄鱼池是长宽为100米的方形,中心坐标为 (0, 0),且东北角坐标为 (50, 50)。池心岛是以 (0, 0) 为圆心、直径15米的圆。给定池中分布的鳄鱼的坐标、以及007一次能跳跃的最大距离,你需要告诉他是否有可能逃出生天。

输入格式:

首先第一行给出两个正整数:鳄鱼数量 N(≤100)和007一次能跳跃的最大距离 D。随后 N 行,每行给出一条鳄鱼的 (x,y) 坐标。注意:不会有两条鳄鱼待在同一个点上。

输出格式:

如果007有可能逃脱,就在一行中输出"Yes",否则输出"No"。

输入样例 1:

14 20
25 -15
-25 28
8 49
29 15
-35 -2
5 28
27 -29
-8 -28
-20 -35
-25 -20
-13 29
-30 15
-35 40
12 12

输出样例 1:

Yes

输入样例 2:

4 13
-12 12
12 12
-12 -12
12 -12

输出样例 2:

No

代码长度限制

16 KB

时间限制

400 ms

内存限制

64 MB

思路

用BFS判断能不能走到鳄鱼池旁边即可。

两个点相邻的依据。两个点的距离<=D。

输入时将所有能在池心岛一脚跳过去的点入队。

AC代码

#include<iostream>
#include<queue>
#include<vector>
#include<cmath>
using namespace std;
int N, D;
int book[110];
struct Node {
    int x, y;
    int i;
};
queue<Node> q;
vector<Node> g;
bool flag = false;
void bfs()
{
    while (!q.empty()) {
        Node node = q.front();
        q.pop();
        for (int i = 0; i < N; i++) {
            if (book[i] == 1 || i == node.i) continue;
            int dx = abs(g[i].x - node.x);
            int dy = abs(g[i].y - node.y);
            int dis = dx * dx + dy * dy;
            if (dis <= D * D) {
                q.push(g[i]);
                book[i] = 1;
                int minedgex = min(abs(g[i].x - 50), abs(g[i].x + 50));
                int minedgey = min(abs(g[i].y - 50), abs(g[i].y + 50));
                if (minedgex <= D || minedgey <= D) { flag = true; return; }
            }
        }
    }
}
int main()
{
    cin >> N >> D;
    double maxdis = (7.5 + D) * (7.5 + D);
    //处理输入,先将能从池心岛一步跳往的点入队
    for (int i = 0; i < N; i++) {
        int x, y;
        cin >> x >> y;
        g.push_back({ x,y,i });
        if (x * x + y * y <= maxdis) {
            q.push({ x,y,i });
            book[i] = 1;
            //该点距离鳄鱼池左右边界的最短距离
            int minedgex = min(abs(x - 50), abs(x + 50));
            //该点距离鳄鱼池上下边界的最短距离
            int minedgey = min(abs(y - 50), abs(y + 50));
            if (minedgex <= D || minedgey <= D) { flag = true; }
        }
    }
    if(!flag) bfs();
    if (flag) cout << "Yes";
    else cout << "No";
}

//

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MySQL 试图

视图功能在 5.0 以后的版本启用 视图是一张虚表。数据表确实包含了具体数据并且保存到硬盘中的实表。视图使用数据检索语句动态生 成的一张虚表。每一次数据服务重启或者系统重启之后&#xff0c;在数据库服务启动期间&#xff0c;会使用创建视图的语 句重新生成视图中的数据&…

这家物流装备公司突破天际:销售额飙升至10亿美元,引领仓储机器人革命!...

导语 大家好&#xff0c;我是智能仓储物流技术研习社的社长&#xff0c;老K。专注分享智能仓储物流技术、智能制造等内容。 新书《智能物流系统构成与技术实践》 法国的Exotec公司在仓储自动化领域取得了显著成就&#xff0c;其销售额已超过10亿美元&#xff0c;成为全球物料搬…

考研数学|《1800》《1000》《660》《880》如何搭配❓

这几本书都是不同阶段对应的习题册 我觉得最舒服的使用就是方式就是基础阶段用《1800题基础部分》然后强化阶段主要刷《880题》并且强化阶段带着刷《660题》 上面是我的使用方式。之所以没有刷《1000题》是因为这本习题册的难度对我来说还是太大了&#xff0c;并且计算量很大…

上海计算机学会 2023年10月月赛 乙组T3 树的连通子图(树、树形dp)

第三题&#xff1a;T3树的连通子图 标签&#xff1a;树、树形 d p dp dp题意&#xff1a;给定一棵 n n n个结点的树&#xff0c; 1 1 1号点为这棵树的根。计算这棵树连通子图的个数&#xff0c;答案对 1 , 000 , 000 , 007 1,000,000,007 1,000,000,007取余数。题解&#xff1…

HTML内联框架

前言&#xff1a; 我们有时候打开网页时会有广告窗的出现&#xff0c;而这些窗口并不是来自于本站的&#xff0c;而是来自于外部网页&#xff0c;只是被引用到了自己网页中而已。这一种技术可以通过内联来实现。 标签介绍&#xff1a; HTML 内联框架元素 (<iframe>) 表示…

基于Springboot的影城管理系统

基于SpringbootVue的影城管理系统的设计与实现 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringbootMybatis工具&#xff1a;IDEA、Maven、Navicat 系统展示 用户登录 首页展示 电影信息 电影资讯 后台登录页 后台首页 用户管理 电影类型管理 放映…

RAG (Retrieval Augmented Generation) 结合 LlamaIndex、Elasticsearch 和 Mistral

作者&#xff1a;Srikanth Manvi 在这篇文章中&#xff0c;我们将讨论如何使用 RAG 技术&#xff08;检索增强生成&#xff09;和 Elasticsearch 作为向量数据库来实现问答体验。我们将使用 LlamaIndex 和本地运行的 Mistral LLM。 在开始之前&#xff0c;我们将先了解一些术…

vue3 生命周期(生命周期钩子 vs 生命周期选项 vs 缓存实例的生命周期)

vue3 支持两种风格书写&#xff1a;选项式 API 和组合式 API 若采用组合式 API &#xff0c;则使用生命周期钩子若采用选项式 API &#xff0c;则使用生命周期选项两者选用一种即可&#xff0c;不建议同时使用&#xff0c;避免逻辑紊乱。 生命周期钩子 在 setup 中使用 onBefo…

Vue 阶段练习:记事本

将 Vue快速入门 和 Vue 指令的学习成果应用到实际场景中&#xff08;如该练习 记事本&#xff09;&#xff0c;我们能够解决实际问题并提升对 Vue 的技能掌握。 目录 功能展示 需求分析 我的代码 案例代码 知识点总结 功能展示 需求分析 列表渲染删除功能添加功能底部统计…

3D目标检测实用技巧(二)- 实现点云(or 体素)向图像平面的投影并可视化

一、引言 受Focals Conv的启发&#xff0c;该论文中通过将点云投影到图片中清晰展现出点云学习后的情况&#xff1a; 本次实现的是体素向图像投影并显示&#xff0c;实现出来的效果如下&#xff1a; 二、 实现细节 1、体素投影到图像坐标系 这里我们参考的是VirConv的投影函…

通过matlab分别对比PSO,反向学习PSO,多策略改进反向学习PSO三种优化算法

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 4.1 粒子群优化算法 (PSO) 4.2 反向学习粒子群优化算法 (OPSO) 4.3 多策略改进反向学习粒子群优化算法 (MSO-PSO) 5.完整程序 1.程序功能描述 分别对比PSO,反向学习PSO,多策略改进反向学…

百货商场用户画像描绘与价值分析

目录 内容概述数据说明实现目标技术点主要内容导入模块1.项目背景1.1 项目背景与挖掘目标 2.数据探索与预处理2.1 结合业务对数据进行探索并进行预处理2.2 将会员信息表和销售流水表关联与合并 3 统计分析3.1 分析会员的年龄构成、男女比例等基本信息3.2 分析会员的总订单占比&…

Python 入门指南(四)

原文&#xff1a;zh.annas-archive.org/md5/97bc15629f1b51a0671040c56db61b92 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 第十章&#xff1a;哈希和符号表 我们之前看过列表&#xff0c;其中项目按顺序存储并通过索引号访问。索引号对计算机来说很有效。它们是整…

使用 Docker 部署 SurveyKing 调查问卷系统

1&#xff09;SurveyKing 介绍 SurveyKing 是一款功能强大、操作简便的开源问卷系统。它不仅满足了用户对问卷调查的基本需求&#xff0c;还提供了丰富的逻辑设置和灵活的问题设置&#xff0c;使得问卷制作更加智能化和个性化。此外&#xff0c;SurveyKing 还具有快速部署和安全…

笔记本电脑上的聊天机器人: 在英特尔 Meteor Lake 上运行 Phi-2

对应于其强大的能力&#xff0c;大语言模型 (LLM) 需要强大的算力支撑&#xff0c;而个人计算机上很难满足这一需求。因此&#xff0c;我们别无选择&#xff0c;只能将它们部署至由本地或云端托管的性能强大的定制 AI 服务器上。 为何需要将 LLM 推理本地化 如果我们可以在典配…

elmentui树形表格使用Sortable拖拽展开行时拖拽bug

1、使用elemntui的el-table使用Sortable进行拖拽&#xff0c;如下 const el this.$el.querySelector(.el-table__body-wrapper tbody) Sortable.create(el, {onEnd: (event) > {const { oldIndex, newIndex } event//拿到更新前后的下标即可完成数据的更新} })2、但是我这…

docker 环境变量设置实现方式

1、前言 docker在当前运用的越来广泛&#xff0c;很多应用或者很多中间软件都有很多docker镜像资源&#xff0c;运行docker run 启动镜像资源即可应用。但是很多应用或者中间件有很多配置参数。这些参数在运用过程怎么设置给docker 容器呢&#xff1f;下面介绍几种方式 2 、do…

Day91:API攻防-接口安全SOAPOpenAPIRESTful分类特征导入项目联动检测

目录 API分类特征-SOAP&OpenAPI&RESTful API分类特征 API常见漏洞 API检测流程 API检测项目-Postman&APIKit&XRAY 工具自动化-SOAP - WSDL Postman 联动burpxray APIKit插件(可联动xray) 工具自动化-OpenApi - Swagger Postman 联动burpxray APIKit…

HarmonyOS开发实例:【分布式邮件】

概述 基于TS扩展的声明式开发范式编程语言编写的一个分布式邮件系统&#xff0c;可以由一台设备拉起另一台设备&#xff0c;每次改动邮件内容&#xff0c;都会同步更新两台设备的信息。效果图如下&#xff1a; 搭建OpenHarmony开发环境 完成本篇Codelab我们首先要完成开发环境…

OpenStack:开源云计算的崛起与发展

目录 一&#xff0c;引言 二&#xff0c;OpenStack的起源 三&#xff0c;OpenStack的版本演进 四&#xff0c;OpenStack跟虚拟化的区别 五&#xff0c;OpenStack组件介绍 1&#xff09;Horizon介绍 2&#xff09;KeyStone介绍 Keystone 功能概览 Keystone 架构详解 3&a…