题目:贴海报
描述:
【题目描述】
Bytetown城市要进行市长竞选,所有的选民可以畅所欲言地对竞选市长的候选人发表言论。为了统一管理,城市委员会为选民准备了一个张贴海报的electoral墙。
张贴规则如下:
1.electoral墙是一个长度为N个单位的长方形,每个单位记为一个格子;
2.所有张贴的海报的高度必须与electoral墙的高度一致的;
3.每张海报以“A B”表示,即从第A个格子到第B个格子张贴海报;
4.后贴的海报可以覆盖前面已贴的海报或部分海报。
现在请你判断,张贴完所有海报后,在electoral墙上还可以看见多少张海报。
【输入格式】
第一行: N M 分别表示electoral墙的长度和海报个数
接下来M行: Ai Bi 表示每张海报张贴的位置
【输出格式】
输出贴完所有海报后,在electoral墙上还可以看见的海报数。
【样例输入】
100 5 1 4 2 6 8 10 3 4 7 10
【样例输出】
4
【提示】
【约束条件】
1 0<= N <= 10000000 1<=M<=1000 1<= Ai <= Bi <=10000000
所有的数据都是整数。数据之间有一个空格
解析:
思路一:暴力
直接30分弃疗……
思路二:浮水法
很容易理解,倒序处理,将每个还未贴过的区域张贴时加上一个标记,标记为指针跳转的位置,每次用一个指针(注意,不要用循环)标记待处理的位置,然后慢慢处理就行了,时间复杂度为$O(N+很小的常数)$,比较不错的算法。
AC代码:
program zht; var n,m,i,t,p,ans:longint; a,b:array[0..1000] of longint; bh:array[0..10000000] of longint; begin assign(input,'ha14d.in'); assign(output,'ha14d.out'); reset(input); rewrite(output); readln(n,m); for i:=1 to m do readln(a[i],b[i]); for i:=m downto 1 do begin t:=a[i]; p:=bh[0]; while t<=b[i] do begin if t>b[i] then break; if bh[t]=0 then begin inc(bh[0]); bh[t]:=b[i]; inc(t);continue; end; if bh[t]>0 then t:=bh[t]+1; end; if p<>bh[0] then inc(ans); end; writeln(ans); close(input); close(output); end.
<Marvolo原创,严禁转载>