DFS(深搜)

复制代码
void dfs(int x, int y) {
    vis[x][y] = true;

    for (int k = 0; k < 方向数; k++) {
        int nx = x + dx[k];
        int ny = y + dy[k];

        if (不合法) continue;
        if (不是我们要搜的目标) continue;
        if (已经访问过) continue;

        dfs(nx, ny);
    }
}

石油储藏

查看题解查看答案

题目描述

Time Limit: 1000 ms

Memory Limit: 256 mb

有一个GeoSurvComp地质勘探公司正在负责探测地底下的石油块。这个公司在一个时刻调查一个矩形区域,并且创建成一个个的格子用来表示众多正方形块。它然后使用测定设备单个的分析每块区域,决定是否有石油。一块有石油小区域被称为一个pocket,假设两个pocket是相邻的,然后他们就是相同石油块的一部分,石油块可能非常的大并且包涵很多的pocket。你的任务就是在一个网格中存在多少个石油块。输入首先给出图的大小,然后给出这个图。*代表没有石油,@代表存在石油。输出每种情况下石油块的个数。

输入输出格式
输入描述:

输入包含一个或多个网格。 每个网格都以包含m和n的行开始,网格中的行和列数为m和n,以单个空格分隔。 如果m = 0,则表示输入结束。 否则为1 <= m <= 100和1 <= n <=100。这之后是m行,每行n个字符(不计算行末字符)。 每个字符对应一个情节,要么是代表没有油的" *",要么是代表油囊的" @"。

输出描述:

在水平,垂直或对角线上都算作相邻,输出每种情况下石油块的个数。

输入输出样例
输入样例#:

复制

复制代码
5 5 
****@
*@@*@
*@**@
@@@*@
@@**@
0 0
输出样例#:

复制

复制代码
2
题目来源
复制代码
中国科学院大学2021年机试题
复制代码
#include<bits/stdc++.h>
using namespace std;

char g[105][105];
int visit[105][105];
int dx[8] = {1, -1, 0, 0, -1, -1, 1, 1};//上下左右, 左上左下右上右下 
int dy[8] = {0, 0, 1, -1, -1, 1, -1, 1};




void DFS(int x, int y, int m, int n){
	visit[x][y] = 1;//
	g[x][y] = '.';
	
	for(int i = 0; i < 8; i ++){
		int nx = x + dx[i];//下一个方向 
		int ny = y + dy[i];
		
		if(nx < 0 || nx >= m || ny < 0 || ny >= n){//越界 
			continue;
		}
		
		if(g[nx][ny] == '*'){//石墙 
			continue; 
		}
		
		if(visit[nx][ny] == 1){//访问过 
			continue;
		}
		
		if(g[nx][ny] == '@'){//是油 
	
			DFS(nx, ny, m, n);
			
		}
		
	}
	return;//找完返回 
}

void BFS(int x, int y, int m, int n){
	g[x][y] = '.';
	visit[x][y] = 1;
	queue<pair<int, int>>q;
	q.push({x, y});//根节点
	
	while(!q.empty()){
		auto it = q.front();
		q.pop();//记得出战 
		
		int sx = it.first;
		int sy = it.second;
		
		for(int i = 0; i < 8; i ++){
			int nx = sx + dx[i];
			int ny = sy + dy[i];
			
			if(nx < 0 || nx >= m || ny < 0 || ny >= n){//越界 
				continue;
			}
			
			if(g[nx][ny] == '*'){//石墙 
				continue;
			}
			
			if(visit[nx][ny] == 1){//访问过 
				continue; 
			}
			
			if(g[nx][ny] == '@'){//石油
				visit[nx][ny] = 1;
				g[nx][ny] = '.';
				q.push({nx, ny});
			}
			
		}
	}
	return;
	
}





int main(){
	int n, m;
	while(cin>>m>>n){
		if(m == 0 && n == 0){
			break;
		}
		
		for(int i = 0; i < m; i ++){
			for(int j = 0; j < n; j ++){
				cin>>g[i][j];
				
				visit[i][j] = 0;//标记为未访问 
			}
		}//
		
		int count = 0; 
		
		for(int i = 0; i < m; i ++){
			for(int j = 0; j < n; j ++){
				 if(g[i][j] == '@' && visit[i][j] == 0){//是油且没有访问过 
				 
				 		count ++;
				 		BFS(i, j, m, n);//宽度遍历 
//				 		DFS(i, j, m, n);//深度遍历
				 		
//				 	for(int i = 0; i < m; i ++){//打印出来看看 
//						for(int j = 0; j < n; j ++){
//								cout<<g[i][j];
//							}
//							cout<<endl;
//						}//
						  
				 }
			}
		}
		

		
		cout<<count<<endl;
		
	} 
	
	
}

graph's connected components(弱化版)

查看题解查看答案

题目描述

Time Limit: 1000 ms

Memory Limit: 256 mb

Given an integers set of m integers,each integer is in the range [0, 2n-1].

A graph is build on the following constraints: if integers X and Y satisfy X&Y=0 (& is bitwise AND operation),X and Y are connected by an undirected edge.Please help PIPI count the number of connected components in the graph!

输入输出格式
输入描述:

Input contains multiple test cases. Each test case starts with a number n(0 <= n <= 12) and m(1<=m<=2^n) . The next line contains m different integers: a1,a2...am ,each integer 0<=ai <2^n.

输出描述:

For each case,print connected components for each group of input data.

输入输出样例
输入样例#:

复制

复制代码
2 3
1 2 3
5 5
5 19 10 20 12
5 6
5 19 10 20 12 0
输出样例#:

复制

复制代码
2
2
1
题目来源
复制代码
中南大学机试题
复制代码
#include<bits/stdc++.h>
using namespace std;

#define N 5000


int visit[N] = {0};
int s[N] = {0};

void DFS(int x, int m, int n){
	visit[x] = 1;//这个点访问过 
	
	for(int i = 0; i < m; i ++){
		if((s[x] & s[i]) == 0 && visit[i] == 0){//有边且没访问过 
			DFS(i, m, n);
		}
	}
	return;
}

int main(){
	int n, m;
	while(cin>>n>>m){
		
		for(int i = 0; i < m; i ++){
			visit[i] = 0;
		}
		
		int x, y;
		for(int i = 0; i < m; i ++){
			cin>>s[i];
		}
		
//		for(int i = 0; i < m ; i ++){
//			for(int j = i + 1; j < m; j ++){
//				x = s[i], y = s[j];
//				if((x & y) == 0){//按下标索引建图, 不要按数值 
//						g[i][j] = 1;
//						g[j][i] = 1;
//				}
//			}
//		}


//		for(int i = 0; i < m ; i ++){
//			for(int j = 0; j < m; j ++){
//				cout<<g[i][j];
//		}
//		cout<<endl;
//		}
		
		
		int count = 0;
		
		for(int i = 0; i < m; i ++){
//				if(g[i][j] == 1 && visit[i] == 0){//有边且没有访问 
				if(visit[i] == 0){//不用看边, 没有访问即可 
					count ++;
					DFS(i, m, n);
			}
		}
		
		cout<<count<<endl;
		
	}
}
相关推荐
junnhwan2 小时前
LeetCode Hot 100——栈
java·数据结构·算法·leetcode·hot 100
sqyno1sky2 小时前
代码动态生成技术
开发语言·c++·算法
superior tigre2 小时前
347 前k个高频元素
数据结构·算法·leetcode
2401_853576502 小时前
C++中的策略模式变体
开发语言·c++·算法
m0_528174452 小时前
C++中的策略模式实战
开发语言·c++·算法
MicroTech20252 小时前
突破非幺正演化难题:MLGO微算法科技研发概率量子算法实现虚时间演化新路径
科技·算法·量子计算
Sagittarius_A*2 小时前
霍夫变换:几何特征检测与量化验证【计算机视觉】
图像处理·人工智能·opencv·算法·计算机视觉·霍夫变换
计算机安禾2 小时前
【C语言程序设计】第30篇:指针与字符串
c语言·开发语言·c++·算法·visualstudio·visual studio code·visual studio
信奥胡老师2 小时前
GESP 2026年3月C++三级(二进制回文串)
开发语言·c++·算法