清橙A1363. 水位 - 清华大学2012年信息学优秀高中学子夏令营

问题描述
  有一个正方形的地区,该地区特点鲜明:如果把它等分为N×N个小正方形格子的话,在每个格子内的任意地点的地表高度是相同的,并且是一个0到M之间的整数。正方形地区的外部被无限高的边界包围。
  该地区可能会有积水。经过多年的观察,人们发现了几个关于积水的重要规律:
  1.
每个格子要么完全没有积水,要么它内部的任意地点的水面高度都是相同的。并且水面高度一定大于地表高度。
  2.
每个格子的水面高度在0~M之间,并且一定是整数。
  3.
对于相邻(必须为边相邻)的两个格子,一定不会出现水自动从一个格子流向另一个格子的情况。也就是说,一定不能出现这两个格子都有水且水面高度不同,或者有水格子的水面比无水格子的地表要高的情况。
  例如,下面图中每个格子里有两个数a/b,说明该格子的地表高度是a,水面高度是b(均为海拔高度),而没有水的格子中b以“?”表示。则左边的情况是符合规律的,而右边的情况并不符合以上规律,因为水可以由2/4的格子流向3/?的格子。

  (图1)

  该地区水文站的工作人员小A想知道,该地区中有多少种不同的水位情况符合规律。你能回答他的这个问题吗?
输入格式
  输入文件的第一行包含两个正整数N和M。
  随后的N行,每行包含N个非负整数。其中第i+1行的第j个数表示该地区第i行第j列格子的地表高度。
输出格式
  输出文件只包含一个整数,即该地区符合规律的水位情况种数。
样例输入
4
3
1 1 1 1
1 2 2 2
1 2 3 3
1 2 3
2
样例输出
6
对样例的说明
  符合规律的水位情况有以下六种 :


数据规模和约定

好一个并查集

首先我们正着想,一开始都有模模糊糊的这个想法,就是划分区域,这几个区域的水一旦高于分界线的高度就会汇合,所以先计算出水位低于分界线的方案数,再算高于分界线的方案数

显然,低于这个高度的方案数是这几个区域的方案数的乘积,高于这个高度的方案数就是最高限制-这个高度,这几个区域的方案数可以递归做

但是递归又难写,时间上也不允许

所以我们从小到大枚举分界线的高度,把这个格子四周的区域合并,一直到整个区域,用并查集维护区域的信息

WA了好多次,原因是高精度数空间没开够,囧......

  1 const
2 maxn=103;
3 s=10000000;
4 fx:array[1..4]of longint=(1,0,-1,0);
5 fy:array[1..4]of longint=(0,1,0,-1);
6 type
7 point=record
8 x,y:longint;
9 end;
10 big=array[0..2000]of int64;
11 var
12 a:array[0..maxn,0..maxn]of longint;
13 b:array[0..maxn*maxn]of point;
14 f,h:array[0..maxn*maxn]of longint;
15 ans:array[0..maxn*maxn]of big;
16 n,m:longint;
17
18 operator *(var a,b:big)c:big;
19 var
20 i,j:longint;
21 begin
22 fillchar(c,sizeof(c),0);
23 for i:=1 to a[0] do
24 for j:=1 to b[0] do
25 inc(c[i+j-1],a[i]*b[j]);
26 c[0]:=a[0]+b[0]-1;
27 for i:=1 to c[0]-1 do
28 begin
29 inc(c[i+1],c[i]div s);
30 c[i]:=c[i]mod s;
31 end;
32 while c[c[0]]>=s do
33 begin
34 c[c[0]+1]:=c[c[0]]div s;
35 c[c[0]]:=c[c[0]]mod s;
36 inc(c[0]);
37 end;
38 end;
39
40 procedure add(var a:big;b:longint);
41 var
42 i:longint;
43 begin
44 inc(a[1],b);
45 i:=1;
46 while a[i]>=s do
47 begin
48 inc(a[i+1],a[i]div s);
49 a[i]:=a[i]mod s;
50 inc(i);
51 end;
52 if i>a[0] then a[0]:=i;
53 end;
54
55 function calc(i,j:longint):longint;
56 begin
57 exit((i-1)*n+j);
58 end;
59
60 function find(x:longint):longint;
61 begin
62 if f[x]=x then exit(x);
63 f[x]:=find(f[x]);
64 exit(f[x]);
65 end;
66
67 procedure swap(var x,y:point);
68 var
69 t:point;
70 begin
71 t:=x;x:=y;y:=t;
72 end;
73
74 procedure sort(l,r:longint);
75 var
76 i,j,y:longint;
77 begin
78 i:=l;
79 j:=r;
80 y:=a[b[(l+r)>>1].x,b[(l+r)>>1].y];
81 repeat
82 while a[b[i].x,b[i].y]<y do
83 inc(i);
84 while a[b[j].x,b[j].y]>y do
85 dec(j);
86 if i<=j then
87 begin
88 swap(b[i],b[j]);
89 inc(i);
90 dec(j);
91 end;
92 until i>j;
93 if i<r then sort(i,r);
94 if j>l then sort(l,j);
95 end;
96
97 procedure print(a:big);
98 var
99 i:longint;
100 k:int64;
101 begin
102 write(a[a[0]]);
103 for i:=a[0]-1 downto 1 do
104 begin
105 k:=s div 10;
106 while k>1 do
107 begin
108 if a[i]<k then write(0)
109 else break;
110 k:=k div 10;
111 end;
112 write(a[i]);
113 end;
114 end;
115
116 procedure main;
117 var
118 i,j,x,y:longint;
119 begin
120 read(n,m);
121 for i:=1 to n do
122 for j:=1 to n do
123 begin
124 read(a[i,j]);
125 h[calc(i,j)]:=a[i,j];
126 b[calc(i,j)].x:=i;
127 b[calc(i,j)].y:=j;
128 end;
129 sort(1,n*n);
130 for i:=1 to n*n do
131 begin
132 f[i]:=i;
133 ans[i][0]:=1;
134 ans[i][1]:=1;
135 end;
136 for i:=1 to n*n do
137 for j:=1 to 4 do
138 if (b[i].x+fx[j]>0) and (b[i].x+fx[j]<=n) and (b[i].y+fy[j]>0) and (b[i].y+fy[j]<=n) then
139 begin
140 x:=find(calc(b[i].x,b[i].y));
141 y:=find(calc(b[i].x+fx[j],b[i].y+fy[j]));
142 if (h[x]>=h[y]) and (x<>y) then
143 begin
144 add(ans[y],h[x]-h[y]);
145 ans[x]:=ans[x]*ans[y];
146 f[y]:=x;
147 end;
148 end;
149 add(ans[find(1)],m-a[b[n*n].x,b[n*n].y]);
150 print(ans[find(1)]);
151 end;
152
153 begin
154 main;
155 end.

清橙A1363. 水位 - 清华大学2012年信息学优秀高中学子夏令营,布布扣,bubuko.com

时间: 2024-10-14 19:47:41

清橙A1363. 水位 - 清华大学2012年信息学优秀高中学子夏令营的相关文章

清橙A1212:剪枝

题面 清橙 Sol 一种新的树上\(DP\)姿势 从左往右按链\(DP\) 做法: 维护两个栈\(S1\),\(S2\) \(S1\)存当前的链 \(S2\)存分叉点以下要改的链 \(Dfs\),弄一个分叉点,之前的链经过它,并且另一条要转移到的链也经过它 那么每次在叶节点时就把\(S1\)最下面的一部分变成\(S2\) 转移 两种情况: 最大值在\(S1\)和在\(S2\)的情况 那么枚举\(S2\),\(S1\)中小于\(S2\)的枚举的值的点就可以转移,并维护\(S1\),\(S2\)的前

【刷题】清橙 A1339 JZPLCM(顾昱洲)

试题来源 2012中国国家集训队命题答辩 问题描述 给定一长度为n的正整数序列a,有q次询问,每次询问一段区间内所有数的lcm(即最小公倍数).由于答案可能很大,输出答案模1000000007. 输入格式 第一行,两个整数,n, q,分别表示数列长度和询问个数. 下面n行,每行一个整数,第i行的整数为ai. 下面q行,每行两个整数l, r,表示询问下标i在[l, r]范围内的ai的lcm. 输出格式 q行.对于每个询问,输出一行,表示对应的答案. 样例输入 3 3 123 234 345 1 2

清橙A1206 小Z的袜子(莫队算法)

A1206. 小Z的袜子 时间限制:1.0s   内存限制:512.0MB 总提交次数:744   AC次数:210   平均分:44.44 将本题分享到: 查看未格式化的试题   提交   试题讨论 试题来源 2010中国国家集训队命题答辩 问题描述 作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿.终于有一天,小Z再也无法忍受这恼人的找袜子过程,于是他决定听天由命-- 具体来说,小Z把这N只袜子从1到N编号,然后从编号L到R(L 尽管小Z并不在意两只袜子是不是

[TS-A1505] [清橙2013中国国家集训队第二次作业] 树 [可持久化线段树,求树上路径第k大]

按Dfs序逐个插入点,建立可持久化线段树,每次查询即可,具体详见代码. 不知道为什么,代码慢的要死,, #include <iostream> #include <algorithm> #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <ctime> #include <vector> using

清橙A1484

http://www.tsinsen.com/ViewGProblem.page?gpid=A1484### 题解: 在线插入并不好做,我们将所有操作离线,变为删除操作. 每次询问的时候对于当前B串所在起始位置及其长度向上向下二分,然后查询区间内合法的当前A串内的匹配点即可. 用树状数组维护(不过我sb的写了线段树,后来才发现···). code: 1 #include<cstdio> 2 #include<iostream> 3 #include<cmath> 4 #

【清橙A1084】【FFT】快速傅里叶变换

问题描述 离散傅立叶变换在信号处理中扮演者重要的角色.利用傅立叶变换,可以实现信号在时域和频域之间的转换. 对于一个给定的长度为n=2m (m为整数) 的复数序列X0, X1, …, Xn-1,离散傅立叶变换将得到另一个长度为n的复数序列Y0, Y1, …, Yn-1.其中 Yi=X0+X1wi+ X2w2i+ X3w3i+…+ Xn-1w(n-1)i 其中w=e2πI/n=cos(2π/n)+I sin(2π/n),称为旋转因子,其中I为虚数单位,I2= –1. 给定输入序列X,请输出傅立叶变

九度OJ 1491 清华大学2012机试 《求1和2的个数》

给定正整数N,函数F(N)表示小于等于N的自然数中1和2的个数之和,例如:1,2,3,4,5,6,7,8,9,10序列中1和2的个数之和为3,因此F(10)=3.输入N,求F(N)的值,1=<N<=10^100(10的100次方)若F(N)很大,则求F(N)mod20123的值. 输入: 输入包含多组测试数据,每组仅输入一个整数N. 输出: 对于每组测试数据,输出小于等于N的自然数中1和2的个数之和,且对20123取模. 样例输入: 10 11 样例输出: 3 5 看了一份别人的代码,十分简略

清橙A1339. JZPLCM(顾昱洲)

http://www.tsinsen.com/ViewGProblem.page?gpid=A1339 题解:https://blog.csdn.net/LOI_DQS/article/details/51251737 对着题解A掉了...然而并不知道为什么要这么转化问题... 复杂度nlog^2n级别吧 1 #include<cstdio> 2 #include<algorithm> 3 #include<map> 4 #include<cmath> 5

【Tsinsen】【A1365】森林旅店

KD-Tree 啊哈~检验了一下自己KD-Tree的学习情况,还算可以,模板至少是记下来了. 支持插入(所以要带重建),查询最近的P个点的距离. 然而题目并没有说是按怎样的顺序输出这P个点?...(事实上是从近到远) 没啥好讲的……就是KD-Tree的裸操作…… 1 //Tsinsen A1365 2 #include<cmath> 3 #include<queue> 4 #include<vector> 5 #include<cstdio> 6 #incl