Educational Codeforces Round 161 (Rated for Div. 2)---->D. Berserk Monsters

一,思路:

1.这是一个模拟链表题,考察对链表的掌握和熟悉程度。在这这题当中有个坑点就是,当一个怪在这回合死了,他任然可以旁边的怪照成伤害(不能着急的给他删掉,不然会出问题)。

2.还有这题很容易就想到,暴力模拟但是时间复杂度:n^2级别是过不了的。所以要优化,找到循环当中那些步骤是冗余的。显然我们可以发现,当一只怪的在这回合没有死掉,且他左右两边的怪也没有死掉,那么下回合他肯定不会死掉。利用这个特点,我们可以用set记录每回合后,那些怪物可能会死掉。

二,代码:

#include <iostream>
#include<cstring>
#include<algorithm>
#include<set>
using namespace std;

const int N=3e5+10;

int ne[N],pre[N];
int arr[N],brr[N];

//记录标记那些怪已近死掉
bool st[N];

void Solved() {

    int n;
    cin>>n;

    for(int i=1;i<=n;i++) cin>>arr[i];
    for(int i=1;i<=n;i++) cin>>brr[i];

    set<int> s;

//当有多组输入时,预处理处理边界情况,会让后面代码很好写,可以不用特判了
    arr[n+1]=0;
    st[n+1]=false;

    for(int i=1;i<=n;i++){

//数组模拟链表
        pre[i]=i-1;
        ne[i]=i+1;

//刚开始所有怪物都可能死掉
        s.insert(i);

//刚开始所有怪物都存活
        st[i]=true;
    }


    for(int i=1;i<=n;i++){

//将这回合已近死了的怪物,存起来不要马上删掉
        set<int> temp;
        int cnt=0;

//判断那些怪物已经死掉了,并标记
        for(auto t: s){
            if(arr[pre[t]]+arr[ne[t]]>brr[t]){
                temp.insert(t);
                st[t]=false;
            }
        }

        s.clear();

//处理删除操作,把下回合可能死掉的怪物存起来
        for(auto t:temp){

            cnt++;

//假如怪物在这回合已经死了的话,就不要等到下一回合了
            if(st[pre[t]]) s.insert(pre[t]);
            if(st[ne[t]]) s.insert(ne[t]);

//链表删除操作
            pre[ne[t]]=pre[t];
            ne[pre[t]]=ne[t];
        }

        cout<<cnt<<" ";
    }

    cout<<endl;
}

int main()
{
    int t;
    cin>>t;

    while(t--) {
        Solved();
    }
    return 0;
}

  • 6
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值