描述
在一个遥远的国度,一侧是风景秀美的湖泊,另一侧则是漫无边际的沙漠。该国的行政区划十分特殊,刚好构成一个N行M列的矩形,其中每个格子都代表一座城市,每座城市都有一个海拔高度。
为了使居民们都尽可能饮用到清澈的湖水,现在要在某些城市建造水利设施。水利设施有两种,分别为蓄水厂和输水站。蓄水厂的功能是利用水泵将湖泊中的水抽取到所在城市的蓄水池中。因此,只有与湖泊毗邻的第1行的城市可以建造蓄水厂。而输水站的功能则是通过输水管线利用高度落差,将湖水从高处向低处输送。故一座城市能建造输水站的前提,是存在比它海拔更高且拥有公共边的相邻城市,已经建有水利设施。
由于第N行的城市靠近沙漠,是该国的干旱区,所以要求其中的每座城市都建有水利设施。那么,这个要求能否满足呢?如果能,请计算最少建造几个蓄水厂;如果不能,求干旱区中不可能建有水利设施的城市数目。
格式
输入格式
输入文件的每行中两个数之间用一个空格隔开。
输入的第一行是两个正整数N和M,表示矩形的规模。
接下来N行,每行M个正整数,依次代表每座城市的海拔高度。
输出格式
输出有两行。如果能满足要求,输出的第一行是整数1,第二行是一个整数,代表最少建造几个蓄水厂;如果不能满足要求,输出的第一行是整数0,第二行是一个整数,代表有几座干旱区中的城市不可能建有水利设施。
样例1
样例输入1
样例输出1
限制
每个测试点1s
提示
本题共有10个测试数据,每个数据的范围如下表所示:
测试数据编号 能否满足要求 N M
1 不能 ≤ 10 ≤ 10
2 不能 ≤ 100 ≤ 100
3 不能 ≤ 500 ≤ 500
4 能 = 1 ≤ 10
5 能 ≤ 10 ≤ 10
6 能 ≤ 100 ≤ 20
7 能 ≤ 100 ≤ 50
8 能 ≤ 100 ≤ 100
9 能 ≤ 200 ≤ 200
10 能 ≤ 500 ≤ 500
对于所有的10个数据,每座城市的海拔高度都不超过10^6。
来源
noip2010提高组复赛
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<queue>
#include<deque>
#include<set>
#include<map>
#include<ctime>
#define LL long long
#define inf 0x7ffffff
#define pa pair<int,int>
#define pi 3.1415926535897932384626433832795028841971
using namespace std;
const int mx[4]={1,0,-1,0};
const int my[4]={0,1,0,-1};
inline LL read()
{
LL x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int n,m,t,w,len;
int a[510][510];
int l[510][510];
int r[510][510];
bool mrk[510][510];
int qx[250010];
int qy[250010];
struct seg{
int l,r;
}d[1000];
bool operator <(const seg &a,const seg &b)
{
return a.l<b.l||a.l==b.l&&a.r<b.r;
}
inline void bfs1()
{
while(t<w)
{
int nx=qx[++t];
int ny=qy[t];
for (int k=0;k<4;k++)
{
int wx=nx+mx[k],wy=ny+my[k];
if (wx<1||wx>n||wy<1||wy>m||mrk[wx][wy])continue;
if (a[wx][wy]>=a[nx][ny])continue;
qx[++w]=wx;
qy[w]=wy;
mrk[wx][wy]=1;
}
}
}
inline void bfs2(int dat[510][510],int x,int y)
{
t=0;w=1;
qx[1]=x;
qy[1]=y;
dat[x][y]=y;
while (t<w)
{
int nx=qx[++t];
int ny=qy[t];
mrk[nx][ny]=1;
for (int k=0;k<4;k++)
{
int wx=nx+mx[k];
int wy=ny+my[k];
if (wx<1||wx>n||wy<1||wy>m||dat[wx][wy])continue;
if (a[wx][wy]<=a[nx][ny])continue;
dat[wx][wy]=dat[nx][ny];
qx[++w]=wx;
qy[w]=wy;
}
}
}
int main()
{
n=read();m=read();
for (int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
a[i][j]=read();
for (int i=1;i<=m;i++)
{
qx[++w]=1;
qy[w]=i;
mrk[1][i]=1;
}
bfs1();
int tot=0;
for (int i=1;i<=m;i++)
if (!mrk[n][i])tot++;
if (tot)
{
printf("0\n%d\n",tot);
return 0;
}
memset(mrk,0,sizeof(mrk));
for (int i=1;i<=m;i++)if (!l[n][i])bfs2(l,n,i);
for (int i=m;i>=1;i--)if (!r[n][i])bfs2(r,n,i);
for (int i=1;i<=m;i++)
if (mrk[1][i])
{
d[++len].l=l[1][i];
d[len].r=r[1][i];
}
sort(d+1,d+len+1);
int now=0,ned=0,mx=0;
for (int i=1;i<=len;i++)
{
if(d[i].l<=now+1)mx=max(mx,d[i].r);
else now=mx,ned++,mx=max(mx,d[i].r);
}
if(now!=m)ned++;
printf("1\n%d\n",ned);
}