首页 > 其他分享 >D. Berserk Monsters

D. Berserk Monsters

时间:2024-01-22 21:25:16浏览次数:23  
标签:gw 遍历 int Monsters 回合 怪物 杀死 Berserk

原题链接

题解

1.最笨的想法,链表,每次在还没被杀死的怪物里遍历一遍,如果被杀死了就从链表中删除这个节点
但是TLE on #7

2.进阶想法,仍然是链表,我们想,如果有些怪物永远都不会被杀死,那我们就没必要遍历它。所以我们从可能被杀死的怪物中遍历
如果一个怪物这个回合被杀死,但是在上个回合中没有被杀死,说明它的两侧怪物发生了变动,说明了上个回合它的两侧怪物被杀死了
所以优化方法如下:一开始把所有的怪物都放进第一回合可能被杀死的集合中,然后遍历集合,如果有怪物被杀死,其两侧的怪物放入下一回合可能被杀的集合中

code

#include<bits/stdc++.h>
using namespace std;
int a[300005]={0},b[300005]={0};
struct
{
    int l,r,a,b;
}gw[300005];
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    gw[0].a=0,gw[0].b=0;
    int t;
    cin>>t;
    while(t--)
    {
        int n;
        cin>>n;
        for(int i=1;i<=n;i++)cin>>gw[i].a;
        for(int i=1;i<=n;i++)cin>>gw[i].b;

        set<int> maybe;//代表可能被删的怪物
        for(int i=1;i<=n;i++)
        {
            gw[i].l=i-1;
            gw[i].r=i+1;
            maybe.insert(i);
        }

        gw[n].r=0;
        int out[300005]={1};//初始化0已被删
        for(int i=1;i<=n;i++)
        {
            vector<int> dellist;
            for(int j : maybe)
            {
                int L=gw[j].l,R=gw[j].r;
                if(gw[j].b<gw[L].a+gw[R].a&&!out[j]) dellist.push_back(j);//如果不判断out,被删掉的元素还有可能继续被删
                //先放再删是因为攻击是同时进行的,还需要当前怪物的配合
            }
            maybe.clear();
            cout<<dellist.size()<<" ";
            for(int j=0;j<dellist.size();j++)
            {
                int now=dellist[j];
                out[now]=1;//代表已被删
                int L=gw[now].l,R=gw[now].r;
                gw[L].r=R;
                gw[R].l=L;
                maybe.insert(L);
                maybe.insert(R);
            }
        }
        cout<<endl;
    }
    return 0;
}

标签:gw,遍历,int,Monsters,回合,怪物,杀死,Berserk
From: https://www.cnblogs.com/pure4knowledge/p/17981091

相关文章

  • CF526F Pudding Monsters 题解
    题目链接:CF或者洛谷析合树真是连续段问题的降智神器先看下题目的一些特殊性,每行每列恰好有一个棋子。考虑特殊性,\(n\timesn\)的棋盘,那么就该判断是否有\(n\)个棋子,容易观察到,也就是相当于每一行并且每一列都有一个棋子。而容易知道,这些棋子所在的行或者列拿出来应当是“......
  • CF1784C Monsters (hard version) 题解 线段树
    题目链接:https://codeforces.com/problemset/problem/1784/C题目大意:你面前有\(n\)只怪兽,每只怪兽都有一个初始血量,你可以进行两类操作:操作1:选择任意一个血量大于\(0\)的怪兽,并将它的血量降低\(1\);操作2:将所有存活的怪物的血量各自减去\(1\),如果存在怪物的血量恰好降为......
  • CF526F Pudding Monsters
    CF526FPuddingMonsters题意给定一个\(n\timesn\)的棋盘,其中有\(n\)个棋子,每行每列恰好有一个棋子。求有多少个\(k\timesk\)的子棋盘中恰好有\(k\)个棋子。\(n\le3\times10^5\)。题解首先注意到每行每列只有一个数这个性质。这意味着我们可以将这个二维数......
  • CF325C - Monsters and Diamonds
    我们首先考虑建图。我们把每个点向它的所有变换连边,把每个变换往它产出的所有点连边,同时点到变换的边有边权,就是变换中\(-1\)的个数。我们首先处理最小值。我们发现,没有出度的点和变换可以一开始就有结果。只要一个点有一个变换是可以有结果的,这个点就可以有结果。变换则不然,必......
  • Codeforces Round 850 (Div. 2, based on VK Cup 2022 - Final Round) E. Monsters (h
    传送门详细题解传送门  抄的ygg代码,向在这里说一下刚开始没看懂的部分。  求答案的时候是把所有的当前为止的所有数值加起来减去一个从1开始并且公差为1的等差数列的前size项和。其中size是当前最多能用到哪个位置,满足前size项能构成1,2,3,....,sz这样的形式。  假设我们......
  • C. Monsters (hard version)
    C.Monsters(hardversion)思路最终肯定是一个阶梯的数组,思考怎么维护阶梯,那些数加进来是无用的。用线段树来维护每个数出现的次数。代码/*最后形成的一定是一个阶......
  • Circle of Monsters[*1600][暴力][构造]
    CircleofMonsters[*1600][暴力][构造]Problem-C-Codeforces有\(N\)头怪兽,他们围成一个环,顺时针编号\(1,2,3,4,\dots,N\)每一头怪兽都有2个属性,一个是它的生......
  • CF1784C Monsters (hard version) 题解
    为了便于表述,下文中用"数"替代怪物的血量。我们换一种不同于easyversion中的计算答案的方法。我们先还是按照easyversion中的贪心操作来消除,当一个数能通过这种贪......