首页 > 代码库 > NOIP2010 引水入城

NOIP2010 引水入城

描述

在一个遥远的国度,一侧是风景秀美的湖泊,另一侧则是漫无边际的沙漠。该国的行政区划十分特殊,刚好构成一个N行M列的矩形,其中每个格子都代表一座城市,每座城市都有一个海拔高度。

为了使居民们都尽可能饮用到清澈的湖水,现在要在某些城市建造水利设施。水利设施有两种,分别为蓄水厂和输水站。蓄水厂的功能是利用水泵将湖泊中的水抽取到所在城市的蓄水池中。因此,只有与湖泊毗邻的第1行的城市可以建造蓄水厂。而输水站的功能则是通过输水管线利用高度落差,将湖水从高处向低处输送。故一座城市能建造输水站的前提,是存在比它海拔更高且拥有公共边的相邻城市,已经建有水利设施。

由于第N行的城市靠近沙漠,是该国的干旱区,所以要求其中的每座城市都建有水利设施。那么,这个要求能否满足呢?如果能,请计算最少建造几个蓄水厂;如果不能,求干旱区中不可能建有水利设施的城市数目。

格式

输入格式

输入文件的每行中两个数之间用一个空格隔开。

输入的第一行是两个正整数N和M,表示矩形的规模。

接下来N行,每行M个正整数,依次代表每座城市的海拔高度。

输出格式

输出有两行。如果能满足要求,输出的第一行是整数1,第二行是一个整数,代表最少建造几个蓄水厂;如果不能满足要求,输出的第一行是整数0,第二行是一个整数,代表有几座干旱区中的城市不可能建有水利设施。

样例1

样例输入1[复制]

 
2 59 1 5 4 38 7 6 1 2

样例输出1[复制]

 
11

限制

每个测试点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。

暴力搜索+剪枝+区间覆盖
一道水题我居然做了那么久。。。Orz
 1 #include<iostream> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5  6 struct Edge 7 { 8     int L,R; 9 }B[502];10 int n,m,ans;11 int F[502];12 int map[502][502];13 int vis[502][502]={0};14 int Dx[4]={-1,0,1,0};15 int Dy[4]={0,1,0,-1};16 17 void dfs(int x,int y,int p)18 {19     vis[x][y]=p;20     if(x==n)21     {22         B[p].L=min(B[p].L,y);23         B[p].R=max(B[p].R,y);24     }25     for(int i=0;i<4;i++)26         if(map[x][y]>map[x+Dx[i]][y+Dy[i]]&&vis[x+Dx[i]][y+Dy[i]]!=p)27             dfs(x+Dx[i],y+Dy[i],p);28 }29 30 bool cmp(Edge a,Edge b)31 {32     return a.L<b.L;33 }34 35 int main()36 {37     memset(map,0x3f3f3f3f,sizeof(map));38     memset(F,0x3f3f3f3f,sizeof(F));39     cin>>n>>m;40     ans=m;41     for(int i=1;i<=n;i++)42         for(int j=1;j<=m;j++)43             cin>>map[i][j];44     for(int i=1;i<=m;i++)45     {46         B[i].L=0x3f3f3f3f;47         B[i].R=0;48         if((i==1)||(i==m)||(map[1][i]>=map[1][i-1])||(map[1][i]>=map[1][i+1]))49             dfs(1,i,i);50     }51     for(int i=1;i<=m;i++)52         if(vis[n][i]>0) ans--;53     if(ans>0) 54     {55         cout<<0<<endl<<ans<<endl;56         return 0;57     }58     sort(B+1,B+m+1,cmp);59     int L = 1;60     while (L <= m) {61         ans++;62         int R = L;63         for (int k=1; k <= m; k++) {64             if (B[k].L > L) break;65             R = max(R,B[k].R);66         }67         L = R + 1;68     }69     cout<<1<<endl<<ans<<endl;70     return 0;71 }

 

NOIP2010 引水入城