版权声明:本文为博主原创文章,转载请注明出处:http://blog.csdn.net/cggwz https://blog.csdn.net/cggwz/article/details/83213174
首先bfs记录那些点可达,然后判断是否可以完全覆盖,如果不可以,统计一下没有覆盖的点的数量输出。
如果可以,有两条性质,第一,每一个河边城市可以到达的干旱城市一定是连续的,第二,对于每一个河边城市能到达的干旱城市区间,他们的区间首段是有序的,即从左到右递增。
所以我们在之前的bfs中要记录每个点可达的河边城市左右端点,然后用贪心进行区间覆盖问题即可。
代码如下:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n,m;
int mapp[505][505];
int vis[505][505];
int l[505][505],r[505][505];
int ans;
void scan(int x,int y){
if(x>=(n+1)||x<=0||y<=0||y>=(m+1)){
return;
}
if(vis[x][y]){
return;
}
vis[x][y]=1;
if(x-1>=1&&mapp[x][y]>mapp[x-1][y]){
scan(x-1,y);
l[x][y]=min(l[x][y],l[x-1][y]);
r[x][y]=max(r[x][y],r[x-1][y]);
}
if(y-1>=1&&mapp[x][y]>mapp[x][y-1]){
scan(x,y-1);
l[x][y]=min(l[x][y],l[x][y-1]);
r[x][y]=max(r[x][y],r[x][y-1]);
}
if(x+1<=n&&mapp[x][y]>mapp[x+1][y]){
scan(x+1,y);
l[x][y]=min(l[x][y],l[x+1][y]);
r[x][y]=max(r[x][y],r[x+1][y]);
}
if(y+1<=m&&mapp[x][y]>mapp[x][y+1]){
scan(x,y+1);
l[x][y]=min(l[x][y],l[x][y+1]);
r[x][y]=max(r[x][y],r[x][y+1]);
}
}
int main(){
scanf("%d%d",&n,&m);
memset(mapp,0x3f,sizeof(mapp));
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
scanf("%d",&mapp[i][j]);
}
}
memset(vis,0,sizeof(vis));
memset(l,0x3f,sizeof(l));
memset(r,0,sizeof(r));
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]==0){
scan(1,i);
}
}
int flag=1;
int num=0;
for(int i=1;i<=m;i++){
if(vis[n][i]==0){
flag=0;
num++;
}
}
printf("%d\n",flag);
if(flag==0){
printf("%d",num);
return 0;
}
ans=0;
int ind=1;
while(ind<=m){
int cur=0;
for(int i=1;i<=m;i++){
if(l[1][i]<=ind){
cur=max(cur,r[1][i]);
}
}
ind=cur+1;
ans++;
}
printf("%d",ans);
return 0;
}