Time Limit: 2 sec / Memory Limit: 1024 MB
Score:425 points
Problem Statement
There is a grid of 𝐻H rows and 𝑊W columns. Some cells (possibly zero) contain magnets.
The state of the grid is represented by 𝐻H strings 𝑆1,𝑆2,…,𝑆𝐻of length 𝑊. If the 𝑗j-th character of 𝑆𝑖 is #
, it indicates that there is a magnet in the cell at the 𝑖i-th row from the top and 𝑗j-th column from the left; if it is .
, it indicates that the cell is empty.
Takahashi, wearing an iron armor, can move in the grid as follows:
- If any of the cells vertically or horizontally adjacent to the current cell contains a magnet, he cannot move at all.
- Otherwise, he can move to any one of the vertically or horizontally adjacent cells.
However, he cannot exit the grid.
For each cell without a magnet, define its degree of freedom as the number of cells he can reach by repeatedly moving from that cell. Find the maximum degree of freedom among all cells without magnets in the grid.
Here, in the definition of degree of freedom, "cells he can reach by repeatedly moving" mean cells that can be reached from the initial cell by some sequence of moves (possibly zero moves). It is not necessary that there is a sequence of moves that visits all such reachable cells starting from the initial cell. Specifically, each cell itself (without a magnet) is always included in the cells reachable from that cell.
Constraints
- 1≤H,W≤1000
- 𝐻 and 𝑊 are integers.
- 𝑆𝑖 is a string of length 𝑊 consisting of
.
and#
. - There is at least one cell without a magnet.
Input
The input is given from Standard Input in the following format:
𝐻H 𝑊W 𝑆1 𝑆2 ⋮ 𝑆𝐻
Output
Print the maximum degree of freedom among all cells without magnets.
Sample Input 1Copy
Copy
3 5 .#... ..... .#..#
Sample Output 1Copy
Copy
9
Sample Input 2Copy
Copy
3 3 ..# #.. ..#
Sample Output 2Copy
Copy
1
For any cell without a magnet, there is a magnet in at least one of the adjacent cells.
Thus, he cannot move from any of these cells, so their degrees of freedom are 1.
Therefore, print 1.
翻译:
思路:
如果没有限制,就是普通的搜索了,暴力跑就好了。加上这个限制,如果我们像连通块一样,提前把某个格子跑到,并且因为 周围上下左右有一个#就不能移动,提前打上标记。后面其实从其他位置出发也能跑到这个格子,这个格子的计数就少了。
那如果我们跑每个点的时候,都对整张地图的vis 标记memset 重置一下,那么总的时间复杂度又太大了。
注意vis,每次进行bfs或者dfs时,要选用没有被任何连通块所访问过的点。
DFS求解
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=1005;
int cnt,n,m,num,ans;
int dx[4]= {0,1,0,-1};
int dy[4]= {-1,0,1,0};
char g[N][N];
int vis[N][N];
bool check(int x,int y) // 检查当前位置是否可以移动
{
for(int i=0; i<4; i++)
{
int nx=x+dx[i];
int ny=y+dy[i];
if(g[nx][ny]=='#') return false; // 如果相邻位置有磁铁,则无法移动
}
return true;
}
void dfs(int x,int y,int id)
{
cnt++;
vis[x][y]=id;
if(!check(x,y)) return;
for(int i=0; i<4; i++)
{
int nx=x+dx[i];
int ny=y+dy[i];
if(nx<1 || nx>n || ny<1 || ny>m) continue;
if(vis[x][y]==vis[nx][ny]) continue;//(nx,ny) 在此连通块下已经访问过了
dfs(nx,ny,id);
}
}
int main()
{
cin>>n>>m;
for(int i=1; i<=n; i++)
for(int j=1; j<=m; j++)
cin>>g[i][j];
for(int i=1; i<=n; i++)
{
for(int j=1; j<=m; j++)
{
if(g[i][j]=='.' && !vis[i][j])
{
cnt=0;
++num;
dfs(i,j,num);
ans=max(ans,cnt);
}
}
}
cout<<ans<<endl;
return 0;
}
BFS求解:
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
typedef long long ll;
const int N=1005;
char g[N][N];
int vis[N][N];
int n,m;
int num,ans,cnt;
int dx[4]={0,-1,0,1};
int dy[4]={1,0,-1,0};
struct node
{
int x;
int y;
int z;
};
bool check(int x,int y)
{
for(int i=0;i<4;i++)
{
int nx=x+dx[i];
int ny=y+dy[i];
if(g[nx][ny]=='#') return false;
}
return true;
}
void bfs(int x,int y,int id)
{
queue<node> q;
vis[x][y]=id;
cnt++;
q.push({x,y,id});
while(!q.empty())
{
node t=q.front();
q.pop();
int tx=t.x;
int ty=t.y;
int tz=t.z;
if(!check(tx,ty)) continue;
for(int i=0;i<4;i++ )
{
int X=tx+dx[i];
int Y=ty+dy[i];
if(X<1 || X>n || Y<1 || Y>m) continue;
if(vis[X][Y]== vis[tx][ty]) continue;
vis[X][Y]=tz;
cnt++;
q.push({X,Y,tz});
}
}
}
void solve()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
cin>>g[i][j];
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(g[i][j]=='.' && !vis[i][j])
{
cnt=0;
num++;
bfs(i,j,num);
ans=max(ans,cnt);
}
}
}
cout<<ans<<endl;
}
int main()
{
solve();
return 0;
}