这个可以爆搜,如果搜出来环的话就一定不合法.
这个时间复杂度是 $O(n^4)$ 的.
但是我们发现,如果向右侧搜的话右侧许多方块会把很多状态都提前搜出来了.
所以我们可以从左向右枚举,搜左面.从右向左枚举,搜右面.
这样时间复杂度就是 $O(n^3)$ 的了.
code:
#include <bits/stdc++.h>
#define N 405
#define setIO(s) freopen(s".in","r",stdin)
using namespace std;
int n,m,vis[N][N],tot,ans[N][N];
int dx[]={0,-1,0,1};
int dy[]={-1,0,1,0};
char str[N][N];
void dfs(int x,int y,int d)
{
if(x<1||x>n||y<1||y>m)
return;
if(vis[x][y])
{
if(vis[x][y]==-1)
tot=1<<30;
return;
}
tot+=2;
vis[x][y]=-1;
dfs(x+dx[d],y+dy[d],d);
d^=str[x][y]=='N'?3:1;
dfs(x+dx[d],y+dy[d],d);
vis[x][y]=1;
}
int main()
{
// setIO("input");
int i,j;
scanf("%d%d",&n,&m);
for(i=1;i<=n;++i)
{
scanf("%s",str[i]+1);
for(j=1;j<=m;++j)
ans[i][j]=1<<30;
}
for(i=1;i<=n;++i)
{
memset(vis,0,sizeof(vis));
tot=0;
for(j=1;j<=m;++j)
{
dfs(i,j,0);
ans[i][j]=min(ans[i][j],tot);
}
memset(vis,0,sizeof(vis));
tot=0;
for(j=m;j;--j)
{
dfs(i,j,2);
ans[i][j]=min(ans[i][j],tot);
}
for(j=1;j<=m;++j)
printf("%d ",ans[i][j]==1<<30?-1:ans[i][j]);
printf("\n");
}
return 0;
}