Codevs P1066 引水入城 2010年NOIP全国联赛提高组

4 篇文章 0 订阅
3 篇文章 0 订阅

Codevs P1066 引水入城  2010年NOIP全国联赛提高组

题目描述 Description

 

在一个遥远的国度,一侧是风景秀美的湖泊,另一侧则是漫无边际的沙漠。该国的行政 区划十分特殊,刚好构成一个N行M列的矩形,如上图所示,其中每个格子都代表一座城 市,每座城市都有一个海拔高度。 为了使居民们都尽可能饮用到清澈的湖水,现在要在某些城市建造水利设施。水利设施 有两种,分别为蓄水厂和输水站。蓄水厂的功能是利用水泵将湖泊中的水抽取到所在城市的 蓄水池中。因此,只有与湖泊毗邻的第1行的城市可以建造蓄水厂。而输水站的功能则是通 过输水管线利用高度落差,将湖水从高处向低处输送。故一座城市能建造输水站的前提,是 存在比它海拔更高且拥有公共边的相邻城市,已经建有水利设施。 由于第N行的城市靠近沙漠,是该国的干旱区,所以要求其中的每座城市都建有水利 设施。那么,这个要求能否满足呢?如果能,请计算最少建造几个蓄水厂;如果不能,求干 旱区中不可能建有水利设施的城市数目。

输入描述 Input Description

输入的每行中两个数之间用一个空格隔开。 输入的第一行是两个正整数N和M,表示矩形的规模。 接下来N行,每行M个正整数,依次代表每座城市的海拔高度。

输出描述 Output Description

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

样例输入 Sample Input

2 5

9 1 5 4 3

8 7 6 1 2

样例输出 Sample Output

  1
  1
数据范围及提示 Data Size & Hint

【数据范围】 本题共有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

 

样例2 说明

 

数据范围

分析

该题是BFS+DP;
一开始理解错误最后DP一直写的线段覆盖的贪心求。。。应该是求得最少蓄水池
那么我们可以用f[i]表示到第i个干旱地区所需要的最少蓄水池数。
f[i]:=min(f[i],f[segment[j].l-1]+1)  (j∈所有的蓄水池)
而这个覆盖边界需要我们通过BFS来计算出来。注意要对于只有一行,即沙漠就可以建蓄水站的情况
对于每个蓄水站其覆盖的必然是一段连续的区间,因为如果不连续断开,在之前已经做出能够全部被覆盖的判断,那肯定由另一个蓄水池过来,必然会造成交叉,这样交叉点其实这个蓄水池就可以向这流,所以必然是一段连续的区间。

————————————————————我是手动分割线————————————————————————


代码如下

program p1066;
const dx:array[1..4] of integer=(0,1,0,-1);
      dy:array[1..4] of integer=(-1,0,1,0);
type rec=record
      l,r:longint;
     end;
var map:array[1..500,1..500] of record
                                 h,c:longint;
                                end;
    segment:array[1..500] of rec;
    f:array[0..500] of longint;
    r,i,j,n,m,ans,k:longint;
    queue:array[1..1000000] of record
                               x,y:longint;
                              end;
    head,rear:longint;
function min(a,b:longint):longint;
begin
 if a>b then exit(b);
 exit(a);
end;

procedure qsort(i,j:longint);
var l,r,mid:longint;
    temp:rec;
begin
 l:=i;
 r:=j;
 mid:=segment[(l+r)>>1].r;
 while l<=r do
  begin
   while segment[l].r
    
    
     
     mid do dec(r);
   if l<=r
    then
     begin
      temp:=segment[l];
      segment[l]:=segment[r];
      segment[r]:=temp;
      inc(l);
      dec(r);
     end;
  end;
 if i
     
     
      
      0) and (x<=n) and (y>0) and (y<=m) and (map[x,y].c=0) and (map[x,y].h
      
      
       
       0) and (x<=n) and (y>0) and (y<=m) and (map[x,y].c=0) and (map[x,y].h>map[queue[head].x,queue[head].y].h)
      then
       begin
        inc(rear);
        queue[rear].x:=x;
        queue[rear].y:=y;
        map[x,y].c:=st;
       end;
    end;
   inc(head);
  end;
end;


begin
 readln(n,m);
 for i:=1 to n do
  for j:=1 to m do
   with map[i,j] do
    begin
     read(h);
     c:=0;
    end;
 bfs0;
 for i:=1 to m do
  if map[n,i].c=0
   then
    begin
     inc(ans);
    end;
 if ans<>0
  then
   begin
    writeln(0);
    writeln(ans);
    exit;
   end;
 writeln(1);
 for i:=1 to n do
  for j:=1 to m do
   map[i,j].c:=0;
 for i:=1 to m do
  bfs(i);
 for i:=1 to m do
  begin
   segment[i].l:=map[1,i].c;
  end;
 for i:=1 to n do
  for j:=1 to m do
   map[i,j].c:=0;
 for i:=m downto 1 do
  bfs(i);
 for i:=1 to m do
  begin
   segment[i].r:=map[1,i].c;
  end;
 ans:=0;
 fillchar(f,sizeof(f),$7f);
 f[0]:=0;
 {qsort(1,m);}
 for i:=1 to m do
  for j:=1 to m do
   begin
    if (segment[j].l<=i) and (segment[j].r>=i)
     then
      begin
       f[i]:=min(f[i],f[segment[j].l-1]+1);
      end;
   end;
 write(f[m]);
end.
      
      
     
     
    
    

评测结果

测试点#flow1.in  结果 :  内存使用量: 256kB 时间使用量: 0ms 
测试点#flow10.in  结果 :  内存使用量: 4076kB 时间使用量: 72ms 
测试点#flow2.in  结果 :  内存使用量: 620kB 时间使用量: 1ms 
测试点#flow3.in  结果 :  内存使用量: 3052kB 时间使用量: 43ms 
测试点#flow4.in  结果 :  内存使用量: 256kB 时间使用量: 0ms 
测试点#flow5.in  结果 :  内存使用量: 128kB 时间使用量: 1ms 
测试点#flow6.in  结果 :  内存使用量: 624kB 时间使用量: 1ms 
测试点#flow7.in  结果 :  内存使用量: 492kB 时间使用量: 1ms 
测试点#flow8.in  结果 :  内存使用量: 624kB 时间使用量: 1ms 
测试点#flow9.in  结果 :  内存使用量: 1260kB 时间使用量: 12ms 
———————————————O__O "…萌萌哒的分割线╮(╯▽╰)╭——————————————————————

多远都要在一起

邓紫棋
想听你听过的音乐 想看你看过的小说
我想收集每一刻 我想看到你眼里的世界
歌曲简谱 歌曲简谱
想到你到过的地方 和你曾渡过的时光
不想错过每一刻 多希望我一直在你身旁
未来何从何去 你快乐我也就没关系
对你我最熟悉 你爱自由我却更爱你
我能习惯远距离 爱总是身不由己
宁愿换个方式至少还能遥远爱着你
爱能克服远距离 多远都要在一起
你已经不再存在我世界里 请不要离开我的回忆
想你说爱我的语气 想你望着我的眼睛
不想忘记每一刻 用思念让我们一直前进
想象你失落的唇印 想象你失约的旅行
想象你离开的一刻 如果我有留下你的勇气
我能习惯远距离 爱总是身不由己
宁愿换个方式至少还能遥远爱着你
爱能克服远距离 多远都要在一起
我已经不再存在你的心里 就让我独自守着回忆
如果阳光永远都炽热 如果彩虹不会掉颜色
你能不能不离开呢
我能习惯远距离 爱总是身不由己
宁愿换个方式至少还能遥远爱着你
爱能克服远距离 多远都要在一起
你已经不再存在我世界里 请不要离开我的回忆
请不要离开 不要离开 我的回忆
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值