引水入城
描述
在一个遥远的国度,一侧是风景秀美的湖泊,另一侧则是漫无边际的沙漠。该国的行政区划十分特殊,刚好构成一个N行M列的矩形,其中每个格子都代表一座城市,每座城市都有一个海拔高度。
为了使居民们都尽可能饮用到清澈的湖水,现在要在某些城市建造水利设施。水利设施有两种,分别为蓄水厂和输水站。蓄水厂的功能是利用水泵将湖泊中的水抽取到所在城市的蓄水池中。因此,只有与湖泊毗邻的第1行的城市可以建造蓄水厂。而输水站的功能则是通过输水管线利用高度落差,将湖水从高处向低处输送。故一座城市能建造输水站的前提,是存在比它海拔更高且拥有公共边的相邻城市,已经建有水利设施。
由于第N行的城市靠近沙漠,是该国的干旱区,所以要求其中的每座城市都建有水利设施。那么,这个要求能否满足呢?如果能,请计算最少建造几个蓄水厂;如果不能,求干旱区中不可能建有水利设施的城市数目。
格式
输入格式
输入文件的每行中两个数之间用一个空格隔开。
输入的第一行是两个正整数N和M,表示矩形的规模。
接下来N行,每行M个正整数,依次代表每座城市的海拔高度。
输出格式
输出有两行。如果能满足要求,输出的第一行是整数1,第二行是一个整数,代表最少建造几个蓄水厂;如果不能满足要求,输出的第一行是整数0,第二行是一个整数,代表有几座干旱区中的城市不可能建有水利设施。
样例1
样例输入1
2 5
9 1 5 4 3
8 7 6 1 2
样例输出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提高组复赛
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<bits/stdc++.h> 2 #define clr(x) memset(x,0,sizeof(x)) 3 #define clr_1(x) memset(x,-1,sizeof(x)) 4 #define LL long long 5 #define INF 0x3f3f3f3f 6 #define mod 000000007 7 #define next nexted 8 using namespace std; 9 const int N=5e2+10; 10 int dirx[4]={0,0,1,-1}; 11 int diry[4]={1,-1,0,0}; 12 int gmap[N][N]; 13 bool inf[N][N]; 14 bool tag[N]; 15 int n,m,k,ans,lt,rt,mx,p; 16 struct seg 17 { 18 int l,r; 19 }segt[N]; 20 struct pos 21 { 22 int x,y; 23 }now,next; 24 queue<pos> que; 25 bool cmp(seg &a,seg &b) 26 { 27 if(a.l==b.l) return a.r>b.r; 28 return a.l<b.l; 29 } 30 void bfs(int tg) 31 { 32 clr(inf); 33 int lt=1000;rt=0; 34 now.x=1; 35 now.y=tg; 36 que.push(now); 37 inf[now.x][now.y]=1; 38 while(!que.empty()) 39 { 40 now=que.front(); 41 que.pop(); 42 if(now.x==n) 43 { 44 if(now.y<lt) lt=now.y; 45 if(now.y>rt) rt=now.y; 46 tag[now.y]=1; 47 } 48 for(int i=0;i<4;i++) 49 { 50 next.x=now.x+dirx[i]; 51 next.y=now.y+diry[i]; 52 if(!inf[next.x][next.y] && gmap[next.x][next.y]<gmap[now.x][now.y]) 53 { 54 que.push(next); 55 inf[next.x][next.y]=1; 56 } 57 } 58 } 59 segt[tg].l=lt; 60 segt[tg].r=rt; 61 return ; 62 } 63 int main() 64 { 65 while(scanf("%d%d",&n,&m)!=EOF) 66 { 67 for(int i=1;i<=n;i++) 68 for(int j=1;j<=m;j++) 69 scanf("%d",&gmap[i][j]); 70 for(int i=0;i<=m+1;i++) 71 gmap[0][i]=gmap[n+1][i]=INF; 72 for(int i=0;i<=n+1;i++) 73 gmap[i][0]=gmap[i][m+1]=INF; 74 clr(tag); 75 for(int i=1;i<=m;i++) 76 bfs(i); 77 ans=0; 78 for(int i=1;i<=m;i++) 79 if(!tag[i]) ans++; 80 if(ans) 81 { 82 printf("0 %d ",ans); 83 continue; 84 } 85 sort(segt+1,segt+m+1,cmp); 86 lt=segt[1].l; 87 rt=segt[1].r; 88 ans=1; 89 p=1; 90 while(rt<m) 91 { 92 mx=0; 93 k=p; 94 for(int i=k+1;i<=m;i++) 95 { 96 if(segt[i].l<=lt) continue; 97 if(segt[i].l>rt+1) break; 98 if(segt[i].r>=mx) 99 { 100 mx=segt[i].r; 101 p=i; 102 } 103 } 104 ++ans; 105 lt=segt[p].l; 106 rt=segt[p].r; 107 } 108 printf("1 %d ",ans); 109 } 110 return 0; 111 }