CCPC 2020 我得重新集结部队

题目链接
模拟就行了,比赛的时候一直一直一直一直不过,WA哭了(OAO)

大概思路, h p hp hp对虫子而言就是表示剩余的 h p hp hp,对狂热者而言就是表示是否离场。
每有一只虫子进来,标识它是个虫子,记录 h p hp hp。每有一个狂热者加入,标识他是狂热者,记 h p > 0 hp>0 hp>0(等于1、2、3…都行),然后遍历已有的虫子,找到最近的一个,然后以该虫子的位置为新位置,以狂热者的攻击范围为半径,扫描在当前攻击范围内的虫子,并使其 h p − = 3 × a t k hp-=3\times atk hp=3×atk,判断攻击范围内是否有虫子存活,如果有,令狂热者 h p < 0 hp<0 hp<0(等于-1、-2…都行)

最后判断, h p > 0 hp>0 hp>0说明虫子没死或者狂热者没有离场,输出Yes,否则输出No

注意使用 long long
注意计算欧几里得距离时,开根号会有精度误差,尽量避免

#include <bits/stdc++.h>
using namespace std;
#define mem(a, b) memset(a, b, sizeof a)
const int N = 2e3 + 10;
//#define LOCAL
int n;
typedef long long ll;
struct point{
    
    
    ll x, y;
    point(){
    
    }
    point(ll x, ll y){
    
    
        this->x = x;
        this->y = y;
    }
};
struct c{
    
    
    ll hp;
    point pt;
    bool is_person;
    c(){
    
    
        this->hp = 0;
    }
    c(ll hp, ll x, ll y){
    
    
        this->hp = hp;
        // this->pt = point(x, y);
        this->pt = {
    
    x, y};
    }
};
ll gcd_dist(point a, point b){
    
    
    ll ch1 = a.x - b.x;
    ll ch2 = a.y - b.y;
    return ch1 * ch1 + ch2 * ch2;
}
c life[N];
int ind;
int main(){
    
    
#ifdef LOCAL
    freopen("in", "r", stdin);
    freopen("out", "w", stdout);
#endif
    cin >> n;
    ind = 0;
    for (int i = 1; i <= n; i++){
    
    
        int f;
        scanf("%d", &f);
        if (f == 1){
    
    
            ll x, y, h;
            scanf("%lld %lld %lld", &x, &y, &h);
            life[++ind] = c(h, x, y);
            life[ind].is_person = false;
        }
        else {
    
    
            ll x, y, atk, r;
            scanf("%lld %lld %lld %lld", &x, &y, &atk, &r);
            life[++ind] = c(1, x, y);
            life[ind].is_person = true;
            int k = -1;
            ll mn = (ll)1e18;
            point t_pt = point(x, y);
            for (int j = 1; j < ind; j++){
    
    
                if (!life[j].is_person && life[j].hp > 0){
    
    
                    if (mn > gcd_dist(life[j].pt, t_pt)){
    
    
                        mn = gcd_dist(life[j].pt, t_pt);
                        k = j;
                    }
                }
            }
            if (k != -1){
    
    
                t_pt = life[k].pt;
                for (int j = 1; j < ind; j++){
    
    
                    if (!life[j].is_person && life[j].hp > 0 && gcd_dist(t_pt, life[j].pt) <= r * r){
    
    
                        life[j].hp -= atk * 3;
                        if (life[j].hp > 0)life[ind].hp = -1;
                    }
                }
            }
        }
    }
    for (int i = 1; i <= ind; i++){
    
    
        if (life[i].hp > 0)puts("Yes");
        else puts("No");
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_43701790/article/details/110375994