[2019 ICPC Asia Nanchang Regional]Resistance

source

题意: 太长了自己看吧,大模拟罢了
谨以此题纪念一去不复返的acm生涯

#include <bits/stdc++.h>
using namespace std;
const int INF = 2e9;
const int MAXN = 404;
const int GUN = 1;
const int BUNKER = 2;
const int PRIVATE = 1;
const int CAPTAIN = 2;

char emchar[MAXN];
int n,k,L,E,T;
int HP1,HP2,DEF;
int r1,r2,d1,d2,d3,t1,t2;

int attackTarget[MAXN];

struct point {
    int x,y;
    point() {}
    point(int _x,int _y) {
        x = _x;
        y = _y;
    }
} road[MAXN];

int dist2(point A, point B) {
    return (A.x - B.x) * (A.x - B.x) + (A.y - B.y) * (A.y - B.y); 
}

struct tower {
    int type;
    point pos;
    int nextUse;
    tower(){}
    tower(int _t,int _x,int _y) {
        type = _t;
        pos = point(_x, _y);
        nextUse = 0;
    }
} towers[MAXN];

struct enemy {
    int type, HP, step, def;
    bool isDead, isEnd;
    int fireUtils;
    int deadFrame;
    enemy() {}
    enemy(int _type) {
        type = _type;
        isDead = false;
        isEnd = false;
        step = 1;
        fireUtils = 0;
        if(type == PRIVATE) {
            HP = HP1;
            def = 0;
        }
        else {
            HP = HP2;
            def = DEF;
        }
    }

    void update() {
        if(isDead || isEnd) return ;
        step ++;
    }

    void damageOff(int damage, int nowFrame, bool isFire) {
        if(type == CAPTAIN && !isFire) {
            HP -= max(1, damage - def);
        } else {
            HP -= damage;
        }
        if(HP < 0) {
            isDead = true;
            deadFrame = nowFrame;
        }
    }

    void attackBy(int towerType, int nowFrame) {
        if(towerType == GUN) {
            damageOff(d1, nowFrame, false);
        } else {
            damageOff(d2, nowFrame, false);
        }
        if(towerType == BUNKER) {
            fireUtils = nowFrame + t2;
        }
    }

    void FireUp(int nowFrame) {
        if(nowFrame <= fireUtils) {
            damageOff(d3, nowFrame, true);
        }
    }

    void getEnd() {
        if(step >= L) isEnd = true;
    }

    void Out() {
        if(isDead) {
            printf("Be killed in the %d-th frame at (%d,%d).\n",deadFrame,road[step].x,road[step].y);
        } else if(isEnd) {
            printf("Arrive with %d HP(s).\n",HP);
        } else {
            printf("Be alive at (%d,%d) with %d HP(s).\n",road[step].x,road[step].y,HP);
        }
    }
} enemys[MAXN];

int nowEnemys;

void updateEnemys(int nowFrame) {
    for(int i=1;i<=nowEnemys;i++) {
        enemys[i].update();
    }
    if(nowEnemys < E) {
        nowEnemys ++;
        enemys[nowEnemys] = enemy(emchar[nowEnemys] - '0');
    }
}

void selectAttackTarget(int nowFrame) {
    for(int i=1;i<=k;i++) {
        int dist = INF, id = -1, r;
        attackTarget[i] = -1;
        if(nowFrame < towers[i].nextUse) {
            continue;
        }
        if(towers[i].type == GUN) r = r1*r1;
        else r = r2*r2;
        for(int j=1;j<=nowEnemys;j++) {
            if(enemys[j].isDead || enemys[j].isEnd || dist2(road[enemys[j].step], towers[i].pos) > r) {
                continue;
            }
            int nowDist = dist2(road[enemys[j].step], towers[i].pos);
            if(nowDist < dist) {
                id = j;
                dist = nowDist;
            }
        }
        attackTarget[i] = id;
    }
}

void goAttack(int nowFrame) {
    for(int i=1;i<=nowEnemys;i++) {
        if(enemys[i].isDead || enemys[i].isEnd) {
            continue;
        }
        enemys[i].FireUp(nowFrame);
    }
    for(int i=1;i<=k;i++) {
        if(attackTarget[i] == -1) continue;
        enemys[attackTarget[i]].attackBy(towers[i].type, nowFrame);
        if(towers[i].type == GUN) {
            towers[i].nextUse = nowFrame + t1;
        }
    }
}

void calcResult(int nowFrame) {
    for(int i=1;i<=nowEnemys;i++) {
        if(enemys[i].isDead || enemys[i].isEnd) continue;
        enemys[i].getEnd();
    }
}

int w33ha(int CASE) {
    scanf("%d%d%d%d%d",&n,&k,&L,&E,&T);
    for(int i=1;i<=L;i++) scanf("%d%d",&road[i].x,&road[i].y);
    scanf("%d%d%d%d%d%d%d", &r1,&d1,&t1,&r2,&d2,&t2,&d3);
    scanf("%d%d%d",&HP1,&HP2,&DEF);
    for(int i=1;i<=k;i++) {
        int t,x,y;
        scanf("%d%d%d",&t,&x,&y);
        towers[i] = tower(t,x,y);
    }
    scanf("%s", emchar+1);
    nowEnemys = 0;
    for(int frame=1;frame<=T;frame++) {
        updateEnemys(frame);
        selectAttackTarget(frame);
        goAttack(frame);
        calcResult(frame);
    }
    printf("Case #%d:\n", CASE);
    for(int i=1;i<=E;i++) {
        enemys[i].Out();
    }
    return 0;
}

int main() {
    int Tcase;scanf("%d",&Tcase);
    for(int i=1;i<=Tcase;i++) w33ha(i);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值