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;
}
}