这题好像是200几年的题,
主要就是贪心加bfs。
求出每一个点流出的水,能遍布哪一些。
有一个优化,就是,当前点要比左右两边都高,才遍历。
而且遍历完之后,最后一行一定是连续的区间,否则就是有位置不能被覆盖。
然后这题就转换成了区间覆盖问题,贪心求解。
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<queue> using namespace std; inline int read(){ int t=1,num=0;char c=getchar(); while(c>‘9‘||c<‘0‘){if(c==‘-‘)t=-1;c=getchar();} while(c>=‘0‘&&c<=‘9‘){num=num*10+c-‘0‘;c=getchar();} return num*t; } const int N=510; const int xt[4]={-1,0,0,1}; const int yt[4]={0,-1,1,0}; int n,m,a[N][N],d[N][N],cov[N],cnt=0; struct note{int x,y;}; struct edge{int l,r;}b[N]; void bfs(int s){ memset(d,0,sizeof(d)); queue<note> q; q.push((note){1,s});d[1][s]=1; while(!q.empty()){ note t=q.front();q.pop(); for(int j=0;j<4;j++){ int x=t.x+xt[j],y=t.y+yt[j]; if(x<1||y<1||x>n||y>m)continue; if(d[x][y]==0&&a[x][y]<a[t.x][t.y]){ d[x][y]=1;q.push((note){x,y}); } } } int f,t;f=t=-1; for(int i=1;i<=m;i++){ if(f==-1&&d[n][i]==1)f=i; if(d[n][i]==1&&d[n][i+1]==0)t=i; cov[i]|=d[n][i]; } if(f!=-1)b[++cnt].l=f,b[cnt].r=t; } bool cmp(edge i,edge j){return i.l<j.l;} void tanxin(){ int ans=1,s=1,nxt=1; sort(b+1,b+1+cnt,cmp); for(int i=1;i<=cnt;i++){ if(b[i].l<=s)nxt=max(nxt,b[i].r); else{ ans++;s=nxt+1; nxt=max(nxt,b[i].r); } if(nxt>=m)break; } printf("1\n%d",ans); } int main() { n=read();m=read(); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) a[i][j]=read(); if(a[1][1]>=a[1][2])bfs(1); for(int i=2;i<m;i++) if(a[1][i-1]<=a[1][i]&&a[1][i]>=a[1][i+1]) bfs(i); if(a[1][m]>=a[1][m-1])bfs(m); int ans=0; for(int i=1;i<=m;i++) if(!cov[i])ans++; if(ans)printf("0\n%d",ans); else tanxin(); return 0; }
本文由Yzyet编写,网址为www.cnblogs.com/Yzyet。非Yzyet同意,禁止转载,侵权者必究。
时间: 2024-10-13 06:19:19