题目传送门
BFS和DFS的简单题目,在这我只讲BFS。
我们先找到一个 *,然后对其进行 BFS,并将所有访问过的 * 标记为 .,在进行 BFS 的同时记录下目前的 * 数量。
当一次 BFS 结束后,我们将统计的数量放入之前开好的桶中,即将 h r e s + 1 h_{res}+1 hres+1。
如果此时 h r e s h_{res} hres 为 0 0 0,则将星系数量加上 1 1 1 并更新此时最大的星系,因为只有 h r e s h_{res} hres 改变了,所以只需要将 h r e s h_{res} hres 和 m a x max max 比较。
结束后再找到一个没有被访问过的 *,然后重复上述过程,直到所有 * 被访问。
#include
using namespace std;
char g[2010][2010];
int n,m,h[20000010],maxn,tots,cnt1,cnt2;
struct node //结构体
{
int x,y;
};
queue<node> q;
int dx[8]={
0,0,-1,1,1,-1,-1,1};
int dy[8]={
1,-1,0,0,1,1,-1,-1};
void bfs(int x,int y) //宽搜
{
node no;
no.x=x;
no.y=y;
q.push(no);
int res=1;
g[no.x][no.y]='.';
while(!q.empty())
{
node fr=q.front();
for(int i=0;i<8;i++)
{
if(g[fr.x+dx[i]][fr.y+dy[i]]=='*')
{
no.x=fr.x+dx[i];no.y=fr.y+dy[i];
q.push(no);
g[fr.x+dx[i]][fr.y+dy[i]]='.';
res++;
}
}
q.pop();
}
if(h[res]==0) cnt2++;
h[res]++; //放入桶中
maxn=max(maxn,h[res]*res);//更新Maxn
cnt1+=res; //总数++
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
cin>>g[i][j];
if(g[i][j]=='*') tots++;
}
}
while(cnt1<tots)
{
int Dx,Dy;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(g[i][j]=='*')
{
Dx=i;
Dy=j;
bfs(Dx,Dy);
}
}
}
}
printf("%d %d",cnt2,maxn);//输出
return 0;
}
还有DFS写法,其实DFS是非常好想的,就是上、下、左、右、左上、右上、左下、右下这四个方位搜索,找到一个标记一个,记住DFS的时候要在未曾遍历过的点上搜索
#include
using namespace std;
const int Maxn=10010;
const int Maxm=100010;
char Mp[Maxn][Maxn];
int n,m;
bool vis[Maxn][Maxn];
int cnt=0,tmp=0,ans=-0x3f3f3f3f; //初始化+定义
void dfs(int x,int y) // 暴力DFS
{
if(x<1 || x>n || y<1 || y>m || Mp[x][y]=='.' || vis[x][y] || Count[x][y]) return ; // return 的原因
vis[x][y]=true; //将它设为经过了
tmp++;
dfs(x+1,y);
dfs(x,y+1);
dfs(x-1,y);
dfs(x,y-1);
dfs(x-1,y-1);
dfs(x-1,y+1);
dfs(x+1,y-1);
dfs(x+1,y+1);
//这上头是八个DFS的方位
vis[x][y]=false; //回溯
}
struct St{
int Score;
}Ans[Maxm];
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
cin>>Mp[i][j]; //输入地图
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(Mp[i][j]=='*' && !vis[i][j]) //要从没有遍历过的点开始遍历
{
tmp=0;
dfs(i,j);
Ans[tmp].Score++;
ans=max(tmp,ans);
}
}
}
int maxn=-0x3f3f3f3f;
for(int i=1;i<=ans;i++)
{
if(Ans[i].Score!=0) //如果这个星座数的星系有的话
{
cnt++; //星系个数++
maxn=max(maxn,i*Ans[i].Score); // Maxn更新
}
}
printf("%d %d\n",cnt,maxn);
return 0;
}