精灵加护

题目大意

有n个武器和m个敌人。
每个敌人都有血量,每个武器都有伤害。
一个武器ai可以消灭一个血量比其伤害低的敌人,或者消灭一个特定的敌人ci。
每个武器只能消灭一个敌人,然后就废了。
问是否能消灭所有敌人。

贪心

如果一个敌人可以被一个武器特定消灭,而且这个武器的伤害原本无法消灭它,那么我们希望这个敌人被特定消灭。因为有多个武器可以实现对这个敌人的特定消灭,我们选择伤害值最小的武器。
接下来,我们希望每个还未被消灭的敌人被伤害尽量小的武器消灭,于是排序扫一遍。

#include<cstdio> 
#include<algorithm>
#define fo(i,a,b) for(i=a;i<=b;i++)
#define fd(i,a,b) for(i=a;i>=b;i--)
using namespace std;
const int maxn=20000+10;
struct dong{
    int x,y;
} a[maxn];
int next[maxn],b[maxn],c[maxn],rank[maxn],id[maxn],last[maxn];
bool bz[maxn],pd[maxn];
int i,j,k,l,t,n,m,ca;
int read(){
    int x=0,f=1;
    char ch=getchar();
    while (ch<'0'||ch>'9'){
        if (ch=='-') f=-1;
        ch=getchar();
    }
    while (ch>='0'&&ch<='9'){
        x=x*10+ch-'0';
        ch=getchar();
    }
    return x*f;
}
bool cmp(dong a,dong b){
    return a.x<b.x;
}
bool cmp2(int x,int y){
    return b[x]<b[y];
}
int getnext(int x){
    x++;
    while (x<=n&&!pd[x]) x++;
    return x;
}
int getnex(int x){
    x++;
    while (x<=m&&!bz[x]) x++;
    return x;
}
int main(){
    freopen("guard.in","r",stdin);freopen("guard.out","w",stdout);
    ca=read();
    while (ca--){
        n=read();m=read();
        fo(i,1,n) a[i].x=read();
        fo(i,1,m) b[i]=read();
        fo(i,1,n) a[i].y=read();
        sort(a+1,a+n+1,cmp);
        fo(i,1,m) id[i]=i;
        sort(id+1,id+m+1,cmp2);
        fo(i,1,m) rank[id[i]]=i;
        fo(i,1,n) a[i].y=rank[a[i].y];
        fo(i,1,m) c[i]=b[id[i]];
        fo(i,1,m) b[i]=c[i];
        fo(i,1,m) last[i]=0;
        fd(i,n,1){
            next[i]=last[a[i].y];
            last[a[i].y]=i;
        }
        fo(i,1,n) pd[i]=1;
        fo(i,1,m) bz[i]=1;
        fd(i,m,1){
            if (last[i]&&a[last[i]].x<b[i]){
                bz[i]=0;
                pd[last[i]]=0;
            }
        }
        i=getnext(0);
        j=getnex(0);
        while (i<=n&&j<=m){
            if (a[i].x>=b[j]){
                pd[i]=0;
                bz[j]=0; 
                i=getnext(i);
                j=getnex(j);
            }
            else i=getnext(i);
        }
        if (j>m) printf("Success\n");else printf("Fail\n");
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值