L2-3 智能护理中心统计
智能护理中心系统将辖下的护理点分属若干个大区,例如华东区、华北区等;每个大区又分若干个省来进行管理;省又分市,等等。我们将所有这些有管理或护理功能的单位称为“管理结点”。现在已知每位老人由唯一的一个管理结点负责,每个管理结点属于唯一的上级管理结点管辖。你需要实现一个功能,来统计任何一个管理结点所负责照看的老人的数量。
注意这是一个动态问题,即随时可能有老人加入某个管理结点,并且老人是有可能从一个管理结点换到另一个管理结点去的。
输入格式:
输入在第一行中给出 2 个正整数:N(≤104)是老人的总数量,即老人们从 1 到 N 编号;M(≤105)是归属关系的总数。
接下来是 M 行,每行给出一对归属关系,格式为:
A B
表示 A
归属于 B
。A
或 B
如果是某个管理结点,则用不超过 4 个大写英文字母表示其名称;如果是某位老人,则用老人的编号表示。这里每个 A
保证只有唯一的上级归属 B
,且只有这个中心系统本身是没有上级归属的。此外,输入保证没有老人自己承担管理结点的角色,即 B
一定是一个管理结点,不可能是老人的编号。但一个管理结点既可以管辖下级结点,也可以直接护理一部分老人。
随后每行给出一个指令,格式为:
指令 内容
如果 指令
为 T
,则表示有老人要入院或转院,内容
是某老人的编号和要去的管理结点的名称,以空格分隔;如果 指令
为 Q
,则 内容
是一个管理结点的名称,意思是统计这个结点所负责照看的老人的数量;如果 指令
为 E
,则表示输入结束。题目保证指令总数不会超过 100 个。
输出格式:
对每个 T
指令,将对应的老人转存到对应的管理结点名下;对每个 Q
指令,在一行中输出对应管理结点所负责照看的老人的数量。读到 E
指令就结束程序。
输入样例:
10 23
EAST CNTR
ZJ EAST
SD EAST
WEST CNTR
SX WEST
HZ ZJ
JN SD
2 JN
8 JTH
6 XAHP
4 ZDYH
5 ZDYH
ZDYH HZ
HUZ ZJ
JX ZJ
1 JX
3 JN
WZ ZJ
XAHP XIAN
XIAN SX
YL SX
JTH XIAN
7 XAHP
Q EAST
T 1 YL
Q EAST
Q SX
T 8 ZDYH
Q HZ
Q HUZ
T 10 XAHP
Q CNTR
E
输出样例:
5
4
4
3
0
9
题解:老人为叶子节点,考虑到每次只有叶子节点的变化,所以只需要贪心计算叶子节点对对应的这条链的贡献即可
// #include<bits/stdc++.h> using namespace std; #define maxn 610938 int n,m; int cnt1=0,cnt2=0,cnt=200000; unordered_map<string,int>mapp; int cot[maxn]; int yezi[maxn]; int pre[maxn]; int main() { cin>>n>>m; string s1,s2; for(int i=1;i<=m;i++) { cin>>s1>>s2; if(s1[0]>='0'&&s1[0]<='9') { if(!mapp[s2]) { ++cnt; mapp[s2]=cnt; } pre[stoi(s1)]=mapp[s2]; } else { if(!mapp[s1]) { ++cnt; mapp[s1]=cnt; } if(!mapp[s2]) { ++cnt; mapp[s2]=cnt; } pre[mapp[s1]]=mapp[s2]; } } for(int i=1;i<=n;i++) { if(pre[i]!=0) { int x=pre[i]; cot[i]=1; while(pre[x]!=x) { cot[x]++; x=pre[x]; } cot[x]++; } } while(1) { char c; cin>>c; if(c=='E') { break; } if(c=='T') { int a; string b; cin>>a>>b; int x=pre[a]; cot[a]=1; while(pre[x]!=x) { cot[x]--; x=pre[x]; } cot[x]--; pre[a]=mapp[b]; int y=pre[a]; cot[a]=1; while(pre[y]!=y) { cot[y]++; y=pre[y]; } cot[y]++; } if(c=='Q') { string x; cin>>x; cout<<cot[mapp[x]]<<endl; } } }
--------------------
L3-1 塔防游戏
有一种简单的塔防游戏是这样的:给定一张由 n 行 m 列个方格子构成的地图,玩家可以任选一个格子放置自己的大本营,还可以在任意一个格子里放置自己的防御堡垒。大本营和每个防御堡垒都有自己的防御能力值 d,表示可以抵御 d 个僵尸的攻击。每一轮游戏开始时,玩家在规定时间内将本级别可以用的防御堡垒布置在地图中,然后僵尸们就从地图边界涌入地图中,向着大本营发起攻击。每轮进攻持续一个固定的时长,结束后剩余的僵尸就原地蒸发。
每队僵尸可以向一个方格的上下左右四个方向移动。如果相邻的目标方格没有堡垒,它们就可以用 1 秒的时间移动过去,否则会被堡垒阻挡或者消灭。对每一队僵尸(从同一地点出发的所有僵尸)而言,每秒会被堡垒消灭 1 个队友,同时消耗掉该堡垒 1 个单位的防御能力。当防御能力降为 0,则该堡垒消失,剩下的僵尸则用 1 秒移动到这个方格继续行进。注意:如果有多支僵尸队都进入了同一个方格,它们并不会合并成一支队伍。
所有的僵尸队都会根据进攻开始时的地图选择被歼灭最少的到达大本营的路线,并且一直按照这个路线行进,中途不因为地图状态的改变而改变。当这样的进攻路径不唯一时,选择能最快到达大本营的路径。题目保证这样的路径所打掉的堡垒的布局是唯一的。
本题就要求你计算出一轮攻击结束时,地图上的布局情况。
输入格式:
输入首先在第一行中给出三个正整数:不超过 100 的 n 和 m,为地图的尺寸;不超过 1000 的 T,为一轮攻击持续的时长。
随后给出 n+2 行,每行给出 m+2 个数字,每行中的数字都用空格分隔,表示攻击开始前地图上的布局。其中第 1 行、第 1 列、第 n+2 行、第 m+2 列