【BOI2012】Peaks
2017-03-01 20:58
681 查看
Description
有一个居住在多山岛屿的登山家,已经攀上了一座山峰,并且要攀爬另外一座更高的山峰。
更精确地说,岛上的每一点都有一个大于零的海拔(海面的海拔为零),并且如果登山家位于海拔Ei的山峰上,那么他的目标是到达其他海拔为Ej(Ej>Ei)的山峰。因为登山家在一个山峰上,所以无法马上向上爬——为了到达一个海拔更高的地点,登山家需要先下山才能上山。下山的路不及上山精彩,因此,登山家想将从当前地点到达更高山峰途中最低点的海拔最大化。
岛屿的地图是一个二维的N*M的矩形网格,并且描述了岛屿每一部分的海拔——格子里的数字表示岛屿对应地区的海拔。如果两个各自有公共点,那么他们相邻。因此,每个格子(除了在边界上的)和其他8个格子相邻。一条路径是一系列的格子,序列中连续的两个格子相邻。一个“平区域”是一个相同海拔格子的集合,并且集合中任意两个格子能够用仅经过这个集合内格子的路径连接。任意两个等高的相邻格子属于同一“平区域” 。一座山峰,是一个相邻的格子中没有更高海拔的“平区域”。
写一个程序,找到所有山峰,并且计算每个山峰到达更高山峰路途中最大的最低海拔。对于岛上最高的山峰(岛上没有更高的山峰),可以确定登山家会离开岛屿寻找更高的山峰,因此,路途中的最低海拔为零(海平面的海拔)。
Input
输入的第一行包含两个整数N和M(1<=N,M<=2000,N*M<=10^5),分别是地图的高和宽。
接下来N行包含岛屿地图的描述。其中每行包含M个空格隔开的整数Eij(1<=Eij<=10^6)。格子Eij(对应地图的i 行j 列)的海拔为输入的i+1行第j 个整数。
Output
输出的第一行须包含一个整数P,岛屿中山峰的个数。接下来P行须每行包含两个整数:这座山峰的海拔及到达更高山峰途中最低点海拔的最大值。这些山峰的信息按照海拔降序输出;如果若干座山峰海拔相同,那么它们按照那个最低点的海拔降序输出。
Sample Input
输入1:
6 6
21 16 9 11 6 7
21 21 10 14 15 9
18 20 8 9 13 14
11 10 9 9 8 13
8 12 12 14 13 8
7 13 12 9 5 1
输入2:
5 3
16 14 16
14 14 15
12 17 16
12 13 10
16 11 16
Sample Output
输出1:
4
21 0
15 11
14 13
13 12
输出2:
5
17 0
16 15
16 14
16 13
16 13
Data Constraint
• 15 分的数据中N<=2或M<=2。
• 50 分的数据中有P<=500。
• 80 分的数据中有P<=5000。
然后按照高度由大到小插入块并且进行合并操作就可以了
但是这题细节很多所以说要耐心实现
有一个居住在多山岛屿的登山家,已经攀上了一座山峰,并且要攀爬另外一座更高的山峰。
更精确地说,岛上的每一点都有一个大于零的海拔(海面的海拔为零),并且如果登山家位于海拔Ei的山峰上,那么他的目标是到达其他海拔为Ej(Ej>Ei)的山峰。因为登山家在一个山峰上,所以无法马上向上爬——为了到达一个海拔更高的地点,登山家需要先下山才能上山。下山的路不及上山精彩,因此,登山家想将从当前地点到达更高山峰途中最低点的海拔最大化。
岛屿的地图是一个二维的N*M的矩形网格,并且描述了岛屿每一部分的海拔——格子里的数字表示岛屿对应地区的海拔。如果两个各自有公共点,那么他们相邻。因此,每个格子(除了在边界上的)和其他8个格子相邻。一条路径是一系列的格子,序列中连续的两个格子相邻。一个“平区域”是一个相同海拔格子的集合,并且集合中任意两个格子能够用仅经过这个集合内格子的路径连接。任意两个等高的相邻格子属于同一“平区域” 。一座山峰,是一个相邻的格子中没有更高海拔的“平区域”。
写一个程序,找到所有山峰,并且计算每个山峰到达更高山峰路途中最大的最低海拔。对于岛上最高的山峰(岛上没有更高的山峰),可以确定登山家会离开岛屿寻找更高的山峰,因此,路途中的最低海拔为零(海平面的海拔)。
Input
输入的第一行包含两个整数N和M(1<=N,M<=2000,N*M<=10^5),分别是地图的高和宽。
接下来N行包含岛屿地图的描述。其中每行包含M个空格隔开的整数Eij(1<=Eij<=10^6)。格子Eij(对应地图的i 行j 列)的海拔为输入的i+1行第j 个整数。
Output
输出的第一行须包含一个整数P,岛屿中山峰的个数。接下来P行须每行包含两个整数:这座山峰的海拔及到达更高山峰途中最低点海拔的最大值。这些山峰的信息按照海拔降序输出;如果若干座山峰海拔相同,那么它们按照那个最低点的海拔降序输出。
Sample Input
输入1:
6 6
21 16 9 11 6 7
21 21 10 14 15 9
18 20 8 9 13 14
11 10 9 9 8 13
8 12 12 14 13 8
7 13 12 9 5 1
输入2:
5 3
16 14 16
14 14 15
12 17 16
12 13 10
16 11 16
Sample Output
输出1:
4
21 0
15 11
14 13
13 12
输出2:
5
17 0
16 15
16 14
16 13
16 13
Data Constraint
• 15 分的数据中N<=2或M<=2。
• 50 分的数据中有P<=500。
• 80 分的数据中有P<=5000。
题解
我们可以先把作为峰的合并为一个块,然后其他点每一个都作为一个块然后按照高度由大到小插入块并且进行合并操作就可以了
但是这题细节很多所以说要耐心实现
var stack,cc:array[0..100005]of longint; father,big,bt:array[0..200005]of longint; go:array[0..9]of longint; a,ans:array[0..100005,1..2]of longint; bz:array[0..400005]of boolean; i,j,k,l,n,m,x,y,z,p,q,max1,max2,s:longint; b:boolean; procedure qsort(l,r:longint); var i,j,mid:longint; begin i:=l; j:=r; mid:=a[(i+j) div 2,1]; repeat while a[i,1]>mid do inc(i); while a[j,1]<mid do dec(j); if i<=j then begin a[0]:=a[i]; a[i]:=a[j]; a[j]:=a[0]; inc(i); dec(j); end; until i>j; if i<r then qsort(i,r); if l<j then qsort(l,j); end; procedure qsort1(l,r:longint); var i,j,mid,midd:longint; begin i:=l; j:=r; mid:=ans[(i+j) div 2,1]; midd:=ans[(i+j) div 2,2]; repeat while (ans[i,1]>mid) or ((ans[i,1]=mid) and (ans[i,2]>midd)) do inc(i); while (ans[j,1]<mid) or ((ans[j,1]=mid) and (ans[j,2]<midd)) do dec(j); if i<=j then begin ans[0]:=ans[i]; ans[i]:=ans[j]; ans[j]:=ans[0]; inc(i); dec(j); end; until i>j; if i<r then qsort1(i,r); if l<j then qsort1(l,j); end; function getfather(x:longint):longint; begin if father[x]=x then exit(x) else father[x]:=getfather(father[x]); exit(father[x]); end; function check(x,y:longint):boolean; begin if (x-1) mod m=0 then if (y=2) or (y=6) or (y=1) then exit(false); if x mod m=0 then if (y=4) or (y=5) or (y=8) then exit(false); exit(true); end; begin //assign(input,'t4.in'); reset(input); assign(input,'peaks.in'); reset(input); assign(output,'peaks.out'); rewrite(output); readln(n,m); for i:=1 to n do begin for j:=1 to m do begin inc(p); read(a[p,1]); a[p,2]:=p; if a[p,1]>max1 then max1:=a[p,1]; cc[p]:=a[p,1]; end; readln; end; go[1]:=-1; go[2]:=-m-1; go[3]:=-m; go[4]:=-m+1; go[5]:=1; go[6]:=m-1; go[7]:=m; go[8]:=m+1; qsort(1,p); for i:=1 to 2*p do father[i]:=i; j:=1; for i:=max1 downto 1 do begin while (j>0) and (a[j,1]=i) do begin if bz[a[j,2]]=true then begin inc(j); continue; end; b:=false; stack[0]:=1; stack[1]:=a[j,2]; l:=0; bz[a[j,2]]:=true; while stack[0]>l do begin inc(l); x:=stack[l]; for k:=1 to 8 do if (go[k]+x>0) and (go[k]+x<=p) then begin if check(x,k)=false then continue; y:=go[k]+x; if cc[y]>cc[x] then b:=true; if (cc[y]=cc[x]) and (bz[y]=false) then begin bz[y]:=true; inc(stack[0]); stack[stack[0]]:=y; end; end; end; if b=false then begin inc(q); for k:=1 to stack[0] do begin father[stack[k]]:=q+p; big[q+p]:=cc[stack[k]]; end; end; inc(j); end; end; z:=0; fillchar(bz,sizeof(bz),false); for i:=1 to p do begin if a[i,1]=1742 then begin a[i,1]:=a[i,1]; end; max2:=0; for j:=0 to 8 do if (a[i,2]+go[j]>0) and (a[i,2]+go[j]<=p) then begin if check(a[i,2],j)=false then continue; if cc[a[i,2]]>cc[a[i,2]+go[j]] then continue; y:=a[i,2]+go[j]; if big[getfather(y)]>=max2 then begin l:=getfather(y); max2:=big[l]; if (cc[y]=max1) and (bz[l]=false) then begin bz[l]:=true; inc(z); ans[z,1]:=cc[y]; ans[z,2]:=0; end; end; end; y:=l; for k:=0 to 8 do if (a[i,2]+go[k]>0) and (a[i,2]+go[k]<=p) then begin if cc[a[i,2]]>cc[a[i,2]+go[k]] then continue; if check(a[i,2],k)=false then continue; x:=getfather(a[i,2]+go[k]); if x<>y then begin if (bz[x]=false) and (x>p) and (big[x]<big[y]) then begin if a[i,1]=735 then begin a[i,1]:=a[i,1]; end; bz[x]:=true; for s:=z+1 to z+bt[x]+1 do begin ans[s,1]:=big[x]; ans[s,2]:=a[i,1]; end; inc(z,bt[x]+1); if a[i,1]=1742 then begin a[i,1]:=a[i,1]; end; end else if big[x]=big[y] then begin inc(bt[y],bt[x]+1); end; father[x]:=y; end; end; end; qsort1(1,z); writeln(z); for i:=1 to z do writeln(ans[i,1],' ',ans[i,2]); close(input); close(output); end.
相关文章推荐
- JZOJ 【BOI2012】Peaks
- JZOJ 3635.【BOI2012】Peaks
- 【JZOJ3635】【BOI2012】Peaks
- 【BOI2012】Mobile jzoj 3636 计算几何
- JZOJ 3636. 【BOI2012】Mobile
- 【BOI2012】Mobile(mobile)
- 【BOI2012】Mobile
- 【bzoj3485: [Baltic2012]peaks】并查集
- 【JZOJ3623】【BOI2012】Mobile
- 【BOI2012】Mobile
- 【JZOJ3636】【BOI2012】Mobile(mobile)
- {题解}[jzoj3636]【BOI2012】Mobile(mobile)
- JZOJ3636. 【BOI2012】Mobile
- jzoj3636. 【BOI2012】Mobile(mobile)
- BZOJ3485 : [Baltic2012]peaks
- 【BOI2012】Mobile(mobile)
- 【JZOJ 3636】【BOI2012】Mobile
- 2012搜狗校园招聘笔试题
- SQL Server 2012 Express安装
- CA服务器的升级 2003—2012