方块游戏 (银河英雄传说)(并查集)

方块游戏
(cubes.pas/c/cpp)
【题目描述】
小A和小B在玩一个方块游戏。编号为1到n(1<=n<=30000)的n个方块正放在地上。每个构成一个立方柱。
游戏开始后,小A会给小B发出p(1<=p<=100000)个指令。
1、移动(M):将包含X的立方柱移动到包含Y的立方柱上。
2、统计(C):统计含X的立方柱中,在X下方的方块数目。
写个程序帮小B完成游戏。
【输入数据】
第1行输入P,之后P行每行输入一条指令。形式为“M X Y”或者“C X”。
输入保证不会有将立方柱放在自己头上的指令。
【输出数据】
每一行,对于每个统计指令,输出其结果。
【样例输入】
6
M 1 6
C 1
M 2 4
M 2 6
C 3
C 4
【样例输出】
1
0
2
【数据范围】
对于40%的数据,n,P≤200。
对于60%的数据,n,P≤2000。
对于100%的数据,n,P≤100000。

是模拟赛考到的一道题,和刷过的“银河英雄传说”(WikiOI 1540)基本一致,我本来以为我会了,没想到还是纠结了很长时间,于是重新收录一下这道题。
(银河英雄传说:http://codevs.cn/problem/1540/

用并查集记录每个方块的最后一次被更新时指向的父亲节点,在询问时进行更新。
因为上一次被记录的时候,父亲节点一定是当时最下面的方块,所以父亲节点下面增加的方块数量也是该节点下面增加方块的数量,在find函数中加入该操作即可。

program mys;
var i,k,x,y,rx,ry,p:longint;
f,d,sum:array[0..60000]of longint;
ch:char;

function find(x:longint):longint;
var t,y:longint;
begin 
if f[x]<>x then 
begin 
t:=f[x];
f[x]:=find(f[x]);
d[x]:=d[x]+d[t];
end;
exit(f[x]);
end;

begin 
assign(input,'cubes.in'); reset(input);
assign(output,'cubes.out'); rewrite(output);
readln(p);
for i:=1 to 30000 do 
begin 
f[i]:=i; d[i]:=0; sum[i]:=1;
end;
for i:=1 to p do 
begin
read(ch);
if ch='M' then read(x,y)
else read(x);
readln;

if ch='M' then 
begin 
rx:=find(x);
ry:=find(y);
f[rx]:=ry;
d[rx]:=sum[ry];
sum[ry]:=sum[ry]+sum[rx];
end
else 
begin 
rx:=find(x);
writeln(d[x]);
end;

end;
close(input);
close(output);
end.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值