[nowcoder 2020] 牛半仙的魔塔(增强版)

一、题目

点此看题

二、解法

值得一说的是本题的数据范围,你看他构造得这么恶心,就知道是为了避免某些情况。人的攻击力一定比怪高,那么人一定打的掉血。怪物的伤害很高,人无论如何都会掉血。这告诉我们只用求减免的伤害最多就行了,也不用多么麻烦的判无解(还没有无解的数据呢!)

不妨从贪心的角度思考,俗话说的好:十个贪心九个排。想要知道最优的选取顺序,可以排序!推理排序规则的方法就是我们看最好的排列方法满足什么条件,然后按照这个条件排就可以了,现在我带着你们来推一推,假设 i , j i,j i,j是两个相邻的怪物( i i i先被打, d d d是防御加成, h h h是战斗轮数):
d [ i ] h [ j ] ≥ d [ j ] h [ i ] d[i]h[j]\geq d[j]h[i] d[i]h[j]d[j]h[i] d [ i ] h [ i ] ≥ d [ j ] h [ j ] \frac{d[i]}{h[i]}\geq \frac{d[j]}{h[j]} h[i]d[i]h[j]d[j]那么我们可以按上述规则排序,但是问题是基于一个树形结构的,也就是排序的结果不一定在树形结构上合法,有些点是"阻挡"了另一些点的选取。怎么办?问题很复杂,考虑减小问题规模

怎么减小问题规模?我们去考虑当前性价比(也就是 d [ i ] h [ i ] \frac{d[i]}{h[i]} h[i]d[i])最高的点,如果他的父亲被选取了就会立即选他(这个结论看似有些跳跃,如果根据"阻挡"的关系还是有蛛丝马迹可寻的),因为这个点是当前性价比最高的,所以这样一定会被优先选择。

有了这个结论,我们可以用一种图论关系来表示这种阻挡下的选取,也就是当前取出最大性价比的点后,用并查集把他和父亲合并到一起,由于父亲还不知道什么时候被选取,我们就把他们缩成一个新的点,轮数和蓝宝石数都是原来的和,再插入到大根堆当中,这样我们就达到了减小问题规模的目的。

如果某一时刻这个父亲是 1 1 1所在的并查集,那么这个并查集就可以按顺序选取了。还有一个细节,合并的完后我们不需要删去原父亲的并查集,因为新点的性价比更高,我们只要保证不会多次操作同一个并查集即可,不难看出时间复杂度是 O ( n log ⁡ n ) O(n\log n) O(nlogn)

b y   t h e   w a y \tt by\space the\space way by the way,函数没打返回值给爷调吐了。

#include <cstdio>
#include <iostream>
#include <queue>
using namespace std;
const int M = 100005;
#define int long long
int read()
{
    int num=0,flag=1;char c;
    while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;
    while(c>='0'&&c<='9')num=(num<<3)+(num<<1)+(c^48),c=getchar();
    return num*flag;
}
int n,tot,f[M],a[M],b[M],c[M],d[M],h[M];
int vis[M],sc[M],fa[M],p[M],sh[M],sd[M];
vector<int> vc[M];
struct node
{
    int u;double t;
    bool operator < (const node &b) const
    {
        return t<b.t;
    }
};priority_queue<node> q;
struct edge
{
    int v,next;
}e[2*M];
void dfs(int u)
{
    for(int i=f[u];i;i=e[i].next)
        if(e[i].v^p[u])
        {
            p[e[i].v]=u;
            dfs(e[i].v);
        }
}
int find(int x)
{
    if(fa[x]!=x) fa[x]=find(fa[x]);
    return fa[x];
}
void fight(int x)//一开始写int会答案错误? 
{
    a[1]-=(b[x]-c[1])*h[x];
    c[1]+=d[x];
}
void fuck(int x)
{
    fight(x);sc[x]=1;
    for(int i=0;i<vc[x].size();i++)
        fuck(vc[x][i]);
}
signed main()
{
    n=read();
    for(int i=1;i<n;i++)
    {
        int u=read(),v=read();
        e[++tot]=edge{v,f[u]},f[u]=tot;
        e[++tot]=edge{u,f[v]},f[v]=tot;
    }
    dfs(1);fa[1]=1;
    a[1]=read();b[1]=read();c[1]=read();
    for(int i=2;i<=n;i++)
    {
        a[i]=read();b[i]=read();c[i]=read();d[i]=read();
        sh[i]=h[i]=(a[i]-1)/(b[1]-c[i]);sd[i]=d[i];fa[i]=i;
        q.push(node{i,1.0*sd[i]/sh[i]});
    }
    sc[1]=1;
    while(!q.empty())
    {
        int u=q.top().u,F=find(p[u]);q.pop();
        if(vis[u]) continue;vis[u]=1;
        if(sc[p[u]]) {fuck(u);continue;}
        sh[F]+=sh[u];sd[F]+=sd[u];
        vc[F].push_back(u);fa[u]=F;
        q.push(node{F,1.0*sd[F]/sh[F]});
    }
	cout<<a[1]<<endl;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: CocosCreator是一款功能强大的游戏开发引擎,而魔塔游戏源码则是指使用CocosCreator开发的一款魔塔类游戏的源代码。 CocosCreator魔塔游戏源码通常包含游戏的各个模块,包括角色控制、战斗系统、地图生成以及游戏UI等。在这个源码中,开发者可以看到一套完整的魔塔游戏框架和逻辑。 角色控制是魔塔游戏源码中的重要部分。开发者可以看到玩家角色的移动、攻击以及技能释放等代码。通过阅读源码,开发者可以了解到游戏角色的行为逻辑,比如怪物移动的规则、装备系统的实现等。 另外,战斗系统是魔塔游戏源码中的关键内容。开发者可以通过查看源码,了解到游戏的攻击和防御计算方式、技能释放和效果表现等细节。这对于学习游戏战斗系统的设计与实现非常有帮助。 地图生成也是源码中的一个重要模块。通过阅读源码,开发者可以了解到地图生成的算法、随机事件的处理、宝箱、商店等游戏元素的放置和生成等细节。 游戏的UI设计也是魔塔游戏源码中不可缺少的一部分。开发者可以通过查看源码,了解到游戏UI的布局、按钮点击事件的处理、弹窗的实现等细节。 总之,通过研究CocosCreator魔塔游戏源码,开发者可以学习到游戏开发中常用的算法和设计思路,同时也可以培养自己的开发能力和创造力。在学习和借鉴源码的基础上,开发者还可以根据自身需求进行二次开发和优化,创作出属于自己的魔塔游戏作品。 ### 回答2: CocosCreator魔塔游戏源码是指使用CocosCreator开发的魔塔类游戏的程序代码。CocosCreator是一款基于Javascript的游戏开发引擎,通过它可以轻松创建多平台的游戏。 魔塔游戏源码通常包含了游戏的一些基本组成部分,如场景、角色、道具、怪物等。它们通过CocosCreator的节点和组件系统进行组织和管理。在源码中,开发者可以了解到游戏的逻辑、界面设计以及各个功能模块的实现方式。 通过使用CocosCreator魔塔游戏源码,开发者可以学习到如何实现一个完整的魔塔游戏。他们可以了解到游戏场景的搭建,通过编辑器创建地图和设置场景元素。他们可以学习到如何处理游戏角色的移动、攻击和受伤等操作,并实现相应的动画效果。另外,他们还可以了解到如何处理游戏道具的使用和怪物的生成与AI行为等。 魔塔游戏源码可以帮助开发者迅速上手游戏开发,节省大量的开发时间。通过对源码的学习和理解,开发者可以根据自己的需要进行二次开发和扩展,实现独具创意的魔塔游戏。 ### 回答3: CocosCreator魔塔游戏源码是基于CocosCreator游戏引擎开发的一种魔塔类游戏的代码。魔塔游戏是一种以策略和冒险为主题的角色扮演游戏,玩家需要在迷宫中探索、寻找宝物、打败敌人,最终达到最深层并击败最终BOSS。 CocosCreator魔塔游戏源码包含了游戏的基本逻辑、界面设计、角色控制、敌人AI、道具系统等各个方面的代码实现。通过阅读源码,我们可以了解到游戏是如何实现地图的生成与呈现、角色的移动和战斗、敌人的行为规则、道具的获取和使用等功能。同时,源码还提供了一些基本的游戏美术资源,如角色、地图瓷砖、敌人等,可以用于快速搭建游戏。 在实际使用源码的时候,我们可以根据自己的需求进行修改和扩展,比如添加新的关卡、设计新的敌人、增加新的道具等。同时,我们也可以根据源码学习到CocosCreator游戏开发的一些基本技巧与规范,例如场景管理、碰撞检测、UI设计等。 总之,CocosCreator魔塔游戏源码是一个可以让我们了解和学习魔塔类游戏开发的实际案例,可以通过对源码的学习和修改,快速搭建自己的游戏项目,并且还可以帮助我们掌握CocosCreator游戏引擎的使用。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值