想用搜索水一水,结果一水就是一下午emmm
用第一层的点去更新其他层的点,并记录能更新到的最远的端点,然后下面判断是否最底层都能到达,都能到达就通过记录的左右端点来更新,使在最少使用的情况下框到最大的范围就行了
代码
//By AcerMo
#include<cmath>
#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int M=555;
int fx[5][2]={{1,0},{0,1},{0,-1},{-1,0}};
int n,m,ans=0;
int high[M][M];
bool vis[M][M];
int l[M][M],r[M][M];
int read()
{
int x=0;char ch=getchar();
while (ch>'9'||ch<'0') ch=getchar();
while (ch>='0'&ch<='9') x=x*10+ch-'0',ch=getchar();
return x;
}
inline void dfs(int x,int y)
{
vis[x][y]=1;
for (int i=0;i<4;i++)
{
int xx=x+fx[i][0];
int yy=y+fx[i][1];
if (xx<1||yy<1||xx>n||yy>m) continue;
if (high[xx][yy]>=high[x][y]) continue;
if (!vis[xx][yy]) dfs(xx,yy);
l[x][y]=min(l[x][y],l[xx][yy]);
r[x][y]=max(r[x][y],r[xx][yy]);
}
return ;
}
int main()
{
n=read();m=read();
for (int i=1;i<=n;i++)
for (int k=1;k<=m;k++)
high[i][k]=read();
memset(l,0x3f,sizeof(l));
for (int i=1;i<=m;i++) l[n][i]=r[n][i]=i;
for (int i=1;i<=m;i++) if (!vis[1][i]) dfs(1,i);
bool flag=0;int cnt=0;
for (int i=1;i<=m;i++)
if (!vis[n][i]) cnt++,flag=1;
if (flag){puts("0");printf("%d",cnt);return 0;}
int le=1;
while (le<=m)
{
int maxa=0;
for (int i=1;i<=m;i++)
if (l[1][i]<=le) maxa=max(maxa,r[1][i]);
cnt++;le=maxa+1;
}
puts("1");
printf("%d",cnt);
return 0;
}