NOIP2010 引水入城

描述

在一个遥远的国度,一侧是风景秀美的湖泊,另一侧则是漫无边际的沙漠。该国的行政区划十分特殊,刚好构成一个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。

暴力搜索+剪枝+区间覆盖
一道水题我居然做了那么久。。。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 }
原文地址:https://www.cnblogs.com/InWILL/p/5902041.html