这次比赛得了152分,第24名,不理想,可能是题目不合胃口吧。
T1 抓猫
比赛时
一开始想到用bfs来找环,但是想到一个样例SWWW,发现如果用bfs的话就错了,然后仔细想想,就发现能用并查集来做。但是,二维的并查集该怎么弄呢(我太弱了)?于是我就想了一种方法,如下如就是给每个格子编号,如下图。
那这样子如何才能在O(1)的复杂度内完成编号呢,其实啊,仔细观察一下图,我们就可以发现一个格子的编号就是
(
i
−
1
)
m
+
j
(i-1)m+j
(i−1)m+j ,不错吧。然后我们就可以愉快地用并查集了。做法就是对于每一个格子,找到里面的猫在这个格子下一步走到的格子,然后用把这两个格子合并(用并查集),最后O(n)循环找到有多少个最古老的祖先。PS:如果想要更快些,可以采用路径压缩。
比赛后
同比赛时
T2 街道
比赛时
比赛时看到这道题就没有思路,我想,诶算了,弃疗。
比赛后
比赛后听了正解,发现又是一道并查集,只不过还要加上hash而已。那应该怎么做呢?
其实很简单,首先设定一个值,就是hash中mod的值,因为这题时间比较紧,所以说对于这个mod,我们就需要定一个素数,我定了
245507
245507
245507(好像
233437
233437
233437 也行)。读入关系时,可以先把每一个字符串的hash值求出来,然后对于平行的情况,我们就把
x
,
y
x,y
x,y 还有
x
+
m
o
d
,
y
+
m
o
d
x+mod,y+mod
x+mod,y+mod 合并起来;如果是垂直的话,我们就把
x
,
y
+
m
o
d
x,y+mod
x,y+mod 还有
x
+
m
o
d
,
y
x+mod,y
x+mod,y 合并起来。对于
W
a
t
e
r
l
o
o
Waterloo
Waterloo 的情况其实就是两条街道同时垂直和平行。
之后对于题目所给的两条街,如果符合
f
i
n
d
(
x
)
=
=
f
i
n
d
(
y
)
∣
∣
f
i
n
d
(
x
+
m
o
d
)
=
=
f
i
n
d
(
y
+
m
o
d
)
find(x)==find(y)||find(x+mod)==find(y+mod)
find(x)==find(y)∣∣find(x+mod)==find(y+mod)
(
f
i
n
d
为
并
查
集
的
函
数
)
(find为并查集的函数)
(find为并查集的函数)的话就输出
“
p
a
r
a
l
l
e
l
”
“parallel”
“parallel” 同样的如果符合垂直的条件,就输出
“
i
n
t
e
r
s
e
c
t
”
“intersect”
“intersect” 其余的全部都是
“
u
n
k
n
o
w
”
“unknow”
“unknow”。这道题就这么完了。
T3 秤
比赛时
比赛的时候打暴力打炸了,无奈交上去,但拿了20分。
比赛后
没想到,听了正解后,发现这道题就是暴力。对于这道题,每次他给你读入两个数,你可以把大的放在前面(为后面做铺垫)。接着,你就可以进行暴力dfs,有以下三种情况:
- 左右两边都是物品,就直接两两判断;
- 如果两边有一个是秤,另一个是物品,那么dfs秤那边,如果秤那边也是合法的再判断物品;
- 两边都是秤,就分别dfs再回溯回来就好了。
这题就没了。
T4 糖果
比赛时
比赛时我想到了带权中位数,然后就这么做了。随后发现不行,但也只能这样做了WA32。
比赛后
比赛后我想到了一种贪心的想法,试了一下,但只能拿76分。
听了正解后,明白了这题是个dp,只不过dp数组是bool数组。
我们可以设
f
i
,
j
f_{i,j}
fi,j 表示到第
i
i
i 个数,最小的差为
j
j
j 可不可行。
只要满足
f
i
−
1
,
j
=
=
t
r
u
e
f_{i-1,j}==true
fi−1,j==true 那么状态转移方程就是:
f
i
,
∣
j
+
k
∗
b
i
−
(
a
i
−
k
)
∗
b
i
∣
=
t
r
u
e
f_{i,|j+k*b_i-(a_i-k)*b_i|}=true
fi,∣j+k∗bi−(ai−k)∗bi∣=true
最终的答案就是
f
n
,
j
=
=
t
r
u
e
f_{n,j}==true
fn,j==true 中最小的
j
j
j
(
0
≤
j
≤
200
)
(0≤j≤200)
(0≤j≤200)。
总结
这次比赛有点“不合胃口”,没事继续努力!加油!
别忘了我的blog!