SDUT 3545 装备合成 (模拟) -- 解题报告
来源:互联网 发布:南京数据恢复中心 编辑:程序博客网 时间:2024/04/29 11:33
题面
装备合成
Time Limit: 1000MS Memory limit: 65536K题目描述
小白很喜欢玩儿LOL,但是无奈自己是个坑货,特别是在装备的选择和合成上,总是站在泉水里为选装备而浪费时间。现在小白试图解决这个问题,为了使问题简单化,我们把游戏中的装备合成规则简化如下:
(1)装备的合成关系构成一棵合成关系树,如图(a)所示,装备的下级装备叫合成小件,直接连接的叫直接合成小件;上级装备叫合成件,直接连接的叫直接合成件。合成树上的每件装备都可以直接购买,如果钱不够也可以先购买这个装备的合成小件。
(2)每个装备都有一个合成价格和一个总价格,装备的总价格=该装备的合成价格+该装备所有直接合成小件的总价格之和(图(a)关系树上面显示的数字就是对应装备的总价格)。
(3)初始的时候(未拥有装备的任何部分),装备的当前价格等于总价格,当前价格会随着购买的小件而发生相应的变化。
(4)如果购买了某个装备,那么它所有上级可合成装备的当前价格都会相应地减少,减少的量等于这个装备的当前价格。
(5)如果购买了某个装备,那么它下级所有合成小件都会被购买,也就是说,这些小件都变成已拥有的状态,但是物品栏里只有最终合成的装备,因为是小件合成了这件装备。
(6)我们认为关系树上的每个装备的直接合成小件都不超过2件,关系树上同一件物品只会出现一次,我们也不考虑物品的出售问题,我们假设物品栏容量无限,金钱无限。
现在问题来了,按照格式给定一棵合成关系树,再给定一系列操作,完成相应的查询,具体格式见输入。输入
多组输入,对于每组数据:
第一行有两个整数n m,分别代表关系树中物品的数量和后续的操作数。(1 <= n,m <= 10^4)
接下来的n行,每行对应一件物品的描述,格式为equipment p k,分别代表装备的名称,合成价格,直接合成小件的个数,然后有k个合成小件的名称synthesis1 synthesis2 … synthesisk。(1 <= p <=10^4 , k <= 2 , 所有物品名称只包含小写英文字母,长度不超过20)
接下来的m行,每行对应一个操作,格式如下:
(1)B equipment ,表示物品equipment被购买。
(2)Q equipment ,表示要查询物品equipment的当前价格。
其中equipment代表物品的名称,保证合法且存在于合成关系树中。
注意:如果B指令购买的装备是当前已经拥有的装备(包括小件),那么忽略该条B购买指令。特别地,如果你已经拥有某件装备,那么查询该物品的当前价格时应该输出这件物品的总价格而不是0输出
对于每次Q查询指令,输出一个整数,代表查询的物品的当前价格。示例输入
8 10
bannerofcommand 600 2 aegisofthelegion fiendishcodex
aegisofthelegion 400 2 nullmagicmantle crystallinebracer
fiendishcodex 465 1 amplifyingtome
nullmagicmantle 450 0
crystallinebracer 100 2 rubycrystal rejuvenationbead
amplifyingtome 435 0
rubycrystal 400 0
rejuvenationbead 150 0
B crystallinebracer
Q fiendishcodex
Q bannerofcommand
B nullmagicmantle
Q aegisofthelegion
B aegisofthelegion
Q bannerofcommand
Q crystallinebracer
B bannerofcommand
Q bannerofcommand示例输出
900
2350
400
1500
650
3000提示
来源
“师创杯”山东理工大学第八届ACM程序设计竞赛
*/
解题思路
没什么可说的,大模拟题一道,对于每一种装备可以用 map 做名称到下标的映射,然后建树,强行模拟。
不多说了,直接上代码:
#include <iostream>#include <cstring>#include <string>#include <map>using namespace std;struct node { int idx; //建树之后的下标 int total, rmd; //总价、剩余价格 int left, right; //左右子节点的下标 bool non_root; //是否是根节点} t[10001];map<string, int> mp;int n, m, cnt;bool bought;void Initialize() { mp.clear(); memset(t, 0, sizeof(t)); cnt = 1;}int GetIndex(string s) { if(mp[s]) return mp[s]; //如果已有映射,直接返回下标 else return mp[s] = cnt++; //否则先存储映射再返回下标}void Build(int root) { if(!t[root].left) { //如果是叶子节点 t[root].idx = cnt++; t[root].total = t[root].rmd; return; } if(t[root].left) { //递归建树,回溯时累加装备价值 Build(t[root].left); t[root].idx = cnt++; t[root].rmd += t[t[root].left].rmd; } if(t[root].right) { //递归建树,回溯时累加装备价值 Build(t[root].right); t[root].rmd += t[t[root].right].rmd; } t[root].total = t[root].rmd; //更新总价值}int Buy(int root, int idx) { if(t[root].rmd == 0) return 0; //如果剩余金钱已为0,则直接返回 int cost; if(idx == t[root].idx) cost = t[root].rmd; if(idx < t[root].idx) cost = Buy(t[root].left, idx); if(idx > t[root].idx) cost = Buy(t[root].right, idx); t[root].rmd -= cost; //剩余价格减去此子物品的花费 return cost;}int Query(int root, int idx) { if(idx == t[root].idx) { if(t[root].rmd==0 || bought) return t[root].total; //已合成则返回总价 else return t[root].rmd; } if(t[root].rmd == 0) bought = true; //如果中途物品剩余价格为0,则标记为true if(idx < t[root].idx) return Query(t[root].left, idx); else return Query(t[root].right, idx);}int main(int argc, char const *argv[]) { ios::sync_with_stdio(false); string name, op; int cost, num, root; while(cin >> n >> m) { Initialize(); for(int i=0; i<n; ++i) { cin >> name >> cost >> num; int root_idx = GetIndex(name); t[root_idx].rmd = cost; if(num >= 1) { //初始化左子树 cin >> name; int sub_idx = GetIndex(name); t[root_idx].left = sub_idx; t[sub_idx].non_root = true; } if(num == 2) { //初始化右子树 cin >> name; int sub_idx = GetIndex(name); t[root_idx].right = sub_idx; t[sub_idx].non_root = true; } } //寻找根节点的下标 for(root=1; t[root].non_root; ++root); cnt = 1; Build(root); //建树 while(m--) { cin >> op >> name; int idx = t[GetIndex(name)].idx; if(op == "B") Buy(root, idx); else { bought = false; cout << Query(root, idx) << endl; } } } return 0;}
- SDUT 3545 装备合成 (模拟) -- 解题报告
- [JLOI2015]装备购买 解题报告
- Code[VS] 1669 运输装备 解题报告
- SDUT 3661 MoutainTop (单调栈) -- 解题报告
- Crafted Item - 合成装备
- BZOJ 3443: 装备合成
- BZOJ3443: 装备合成
- HDU3004解题报告【模拟题】
- Hdu 1049模拟解题报告
- SDUT——Mirror, Mirror on the Wall 解题报告
- SDUT 2059 简单n! (大数阶乘) -- 解题报告
- SDUT 3014 硬币问题 (动态规划) -- 解题报告
- SDUT 3100 动态规划? (动态规划) -- 解题报告
- SDUT 3513 皮卡丘的梦想 (二进制+线段树) -- 解题报告
- SDUT 3554 无尽走廊 (动态规划) -- 解题报告
- SDUT 3548 疯狂的小金 (贪心) -- 解题报告
- SDUT 3556 数列求和2 (动态规划) -- 解题报告
- SDUT 3271 飞花的传送门 (凸包) -- 解题报告
- 第十五周项目一 程序填空
- arm-none-linux-gnueabi-gcc install
- java编程思想读书笔记
- Python入门:计算目录下的文件大小和
- 栈(stack)和队列(queue)的简单实例
- SDUT 3545 装备合成 (模拟) -- 解题报告
- DetachedCriteria多条件查询or,disjunction
- Parquet 读写
- WordPress init admin_init 加载多次js文件后,js扩展不能运行
- ZooKeeper程序员指南(转)
- hibernate 缓存
- Android中多图片选择器PhotoPicker库的使用(仿微信,秒杀MultiImageSelector)
- 监控WebBrowser的内容是否发生改变
- 基于 Token 的身份验证