首页 > 其他分享 >一天又过去了, 杀蚂蚁也结束咧

一天又过去了, 杀蚂蚁也结束咧

时间:2022-10-10 08:00:24浏览次数:50  
标签:const 蚂蚁 Point double 一天 pos Vec operator 结束

因为是专门关于这个的博客, 所以代码就不折叠了

谁有能想到最后的最后, 真正一直恶心着我的是我把 last_pos 发挥作用之前改成了 pos, 用了一下午和一早上去手模

#include <cmath>
#include <cstdio>
#include <vector>
#include <algorithm>
namespace La_Pluma_math{
    const double eps = 1e-10;
    typedef int Point_type;                                      // 如果点的坐标会出现小数, 把这个 int 改成 double 就可以了(int 的时候应该也不会和向量互转吧。。。不然可能出锅?)
    struct Point; struct Vec; struct Line; struct Segment;
    double check_0(double);                                      // 判丢精的 0
    double dis(const Point, const Point);                        // 点到点的距离
    double dis(const Point, const Line);                         // 点到直线距离
    double dis(const Line, const Point);                         // 直线到点距离
    double dis(const Point, const Segment);                      // 点到线段距离
    double dis(const Segment, const Point);                      // 线段到点距离
    struct Point{                                                // 点
        Point_type x, y;                    
        Point():x(), y(){}                                       // 默认构造函数
        Point(const Vec);                                        // 用向量初始化 (感觉非常SB)
        Point(Point_type, Point_type);                           // 用坐标初始化
        bool operator == (const Point);                          // 判断是否为同一个点
        bool operator != (const Point);                          // 判断是否不为同一个点
    };                   
    struct Vec{                                                  // 向量
        double x, y;                    
        Vec():x(), y(){}                                         // 默认构造函数
        Vec(const Point);                                        // 用点初始化
        Vec(const Segment);                                      // 用线段初始化
        Vec(double, double);                                     // 用坐标初始化
        Vec(const Point, const Point);                           // 用两个点初始化 (起点和终点)
        Vec(double, double, double, double);                     // 用两个坐标初始化 (起点和终点)
        Vec    operator +  (const Vec);                          // 向量加
        Vec    operator -  (const Vec);                          // 向量减
        double operator ^  (const Vec);                          // 向量叉积的模
        double operator *  (const Vec);                          // 向量点积
        double operator ~  ();                                   // 向量的模
        Vec    operator += (const Vec);                          // 以下处理一些奇怪的运算符
        Vec    operator -= (const Vec);                          // 结果发现也就这些
        Vec    operator -  ();                                   // 又有谁能想到减号也可以是单目运算符呢
        bool   operator == (const Vec);                          // 判断是否为共线向量
        bool   operator != (const Vec);                          // 判断是否不为共线向量
    };                
    struct Line{                                                 // 直线
        double A, B, C;                  
        Line():A(), B(), C(){}                                   // 默认构造函数
        Line(const Segment);                                     // 用线段初始化
        Line(double, double);                                    // 用斜截式初始化
        Line(const Point, const Point);                          // 用两个点初始化
        Line(double, double, double, double);                    // 用两个坐标初始化 
        bool operator == (const Line);                           // 判断是否为同一条直线
        bool operator != (const Line);                           // 判断是否不为同一条直线
    };                  
    struct Segment{                                              // 线段
        Point a, b;                
        Segment():a(),b(){}                                      // 默认构造函数
        Segment(const Point, const Point);                       // 用两个端点初始化
        Segment(Point_type, Point_type, Point_type, Point_type); // 用两个坐标初始化
        double operator ~ ();                                    // 线段的长度
        bool operator <  (Segment);                              // 万能的小于号
        bool operator >  (Segment);                              // 进行
        bool operator <= (Segment);                              // 一个
        bool operator >= (Segment);                              // 重的载
        bool operator == (Segment);                              // 判断线段的长度是否相等
        bool operator != (Segment);                              // 判断线段的长度是否不相等
    };

         Point::Point(const Vec a)                { x = a.x, y = a.y; }
         Point::Point(Point_type x, Point_type y) { this->x = x, this->y = y; }
    bool Point::operator == (const Point a)       { return x == a.x && y == a.y; }
    bool Point::operator != (const Point a)       { return !(*this == a); }

           Vec::Vec(const Point a)                { x = a.x, y = a.y; }
           Vec::Vec(const Segment a)              { *this = Vec(a.a, a.b); }
           Vec::Vec(const Point a, const Point b) { *this = Vec(b) - Vec(a); }
           Vec::Vec(double x, double y)           { this->x = x, this->y = y; }
    Vec    Vec::operator +  (const Vec b)         { return Vec(x + b.x, y + b.y); } 
    Vec    Vec::operator -  (const Vec b)         { return Vec(x - b.x, y - b.y); } 
    Vec    Vec::operator -  ()                    { return Vec(-x     , -y     ); }
    double Vec::operator ^  (const Vec b)         { return x * b.y - b.x * y; }
    double Vec::operator *  (const Vec b)         { return x * b.x + y * b.y; }
    double Vec::operator ~  ()                    { return sqrt(x * x + y * y); } 
    Vec    Vec::operator += (const Vec b)         { return *this = *this + b; }
    Vec    Vec::operator -= (const Vec b)         { return *this = *this - b; }
    bool   Vec::operator == (const Vec b)         { return check_0(y / b.y - x / b.x) == 0; }
    bool   Vec::operator != (const Vec b)         { return !(*this == b); }

    Line::Line(const Segment a)                        { *this = Line(a.a, a.b); }
    Line::Line(double k, double b)                     { A = k, B = 0, C = b; }
    Line::Line(double a, double b, double c, double d) { *this = Line(Point(a, b), Point(c, d)); }
    Line::Line(const Point a, const Point b){
        if(a.x == b.x) A = 1, B = 0, C = -a.x;
        else if(a.y == b.y) A = 0, B = 1, C = -a.y;
        else A = (double)(a.y - b.y) / (a.x - b.x), B = -1, C = (double)(a.x * b.y - b.x * a.y) / (a.x - b.x);
    }
    bool Line::operator == (const Line a) { return check_0(A * a.B - B * a.A) == 0 && check_0(A * a.C - C * a.A) == 0 && check_0(B * a.C - C * a.B) == 0; }
    bool Line::operator != (const Line a) { return !(*this == a); }
    
           Segment::Segment(const Point a, const Point b)     { this->a = a, this->b = b; }
           Segment::Segment(Point_type a, Point_type b, Point_type c, Point_type d) { *this = Segment(Point(a, b), Point(c, d)); }// 因为一些显然的问题, 这里就不对齐了
    double Segment::operator ~  ()                            { return dis(a, b); }
    bool   Segment::operator <  (Segment a)                   { return (~(*this)) < (~a); }
    bool   Segment::operator >  (Segment a)                   { return a < *this; }
    bool   Segment::operator <= (Segment a)                   { return !(*this > a); }
    bool   Segment::operator >= (Segment a)                   { return !(*this < a); }
    bool   Segment::operator == (Segment a)                   { return !(*this < a) && !(*this > a); }
    bool   Segment::operator != (Segment a)                   { return  (*this < a) ||  (*this > a); }

    double check_0(double a){ return fabs(a) < eps ? 0 : a; }
    double dis(const Point pos1, const Point pos2) { return check_0(sqrt((pos1.x - pos2.x) * (pos1.x - pos2.x) + (pos1.y - pos2.y) * (pos1.y - pos2.y))); }
    double dis(const Line link, const Point pos)   { return check_0(fabs(link.A * pos.x + link.B * pos.y + link.C) / sqrt(link.A * link.A + link.B * link.B)); }
    double dis(const Point pos, const Line link)   { return dis(link, pos); }
    double dis(const Point pos, const Segment Seg) { return dis(Seg,  pos); }
    double dis(const Segment Seg, const Point pos) { 
        Vec vector1(Seg.a, pos);
        Vec vector2(Seg.b, pos);
        Vec vector3 = Seg;
        if(check_0(vector1 * vector3) < 0) return ~vector1;
        if(check_0(vector2 * vector3) > 0) return ~vector2;
        return check_0(fabs((vector1 ^ vector3) / (~vector3)));
    }
} using namespace La_Pluma_math;
int n, m, id_cnt, end_tim, now_tim;
int sum_of_tower, agg_of_tower, r_of_tower;
int map[10][10], vis[10][10];
const int yy[] = {1, 0, -1, 0}, xx[] = {0, 1, 0, -1};
const int xy[4][4] = {
    {3, 2, 1, 0},// 东
    {0, 3, 2, 1},// 南
    {1, 0, 3, 2},// 西
    {2, 1, 0, 3} // 北
};
Point tower[22];
struct antbuster{
    int years, HP, Lv;
    Point last_pos, pos;
    bool target;
};
typedef std::vector<antbuster>::iterator vec_it;
double init_HP(const antbuster &a){ return pow(1.1, a.Lv) * 4; }
std::vector<antbuster> ant;

void get_new_ant(){
    ++id_cnt;
    antbuster tmp;
    tmp.Lv       = ceil((double)id_cnt / 6);
    tmp.HP       = init_HP(tmp);
    tmp.years    = 0;
    tmp.target   = false;
    tmp.pos      = Point(0, 0);
    tmp.last_pos = Point(0, 0);
    vis[0][0] = true;
    ant.push_back(tmp);
}
bool check_mov(vec_it a, int i){ 
    return a->pos.x + xx[i] > n || a->pos.x + xx[i] < 0 || 
           a->pos.y + yy[i] > m || a->pos.y + yy[i] < 0 || 
           vis[a->pos.x + xx[i]][a->pos.y + yy[i]]      || 
           (a->last_pos.x - a->pos.x == xx[i] && a->last_pos.y - a->pos.y == yy[i]);
}
vec_it find_target(){
    if(ant.empty()) return ant.end();
    for(vec_it i = ant.begin(); i != ant.end(); ++i) if(i->target) return i;
    return ant.end();
}
void mov(vec_it a){
    int flag1[4] = {1, 1, 1, 1}, flag2[4] = {1, 1, 1, 1}, tmp = 0;
    #define choice ((flag1[0] & flag2[0]) + (flag1[1] & flag2[1]) + (flag1[2] & flag2[2]) + (flag1[3] & flag2[3]))
    for(int i = 0; i < 4; ++i) if(check_mov(a, i)) flag1[i] = 0;
    for(int i = 0; i < 4; ++i) if(flag1[i]) tmp = std::max(tmp, map[a->pos.x + xx[i]][a->pos.y + yy[i]]);
    for(int i = 0; i < 4; ++i) if(map[a->pos.x + xx[i]][a->pos.y + yy[i]] < tmp) flag2[i] = 0;
    if(choice == 0){
        a->last_pos = a->pos;
        return; 
    }
    tmp = 0;
    while(!(flag1[tmp] && flag2[tmp])) ++tmp;
    if(a->years && a->years % 5 == 4)
        for(int i = 0; i < 4; ++i)
            if(!check_mov(a, xy[tmp][i])){
                tmp = xy[tmp][i];
                break;
            }
    vis[a->pos.x][a->pos.y] = false;
    a->last_pos = a->pos;
    a->pos.x += xx[tmp], a->pos.y += yy[tmp];
    vis[a->pos.x][a->pos.y] = true;
}
void fire(Point a){
    double min_dis = 1e18; vec_it aim = ant.end();
    for(vec_it i = ant.begin(); i != ant.end(); ++i){
        double now_dis = dis(a, i->pos);
        if(now_dis <= r_of_tower && now_dis < min_dis) min_dis = now_dis, aim = i;
    }
    if(aim != ant.end()) aim->HP -= agg_of_tower; 
}
void fire(Point a, vec_it it){
    if(dis(a, it->pos) <= r_of_tower){
        Segment light(a, it->pos);
        for(vec_it i = ant.begin(); i != ant.end(); ++i) if(dis(light, i->pos) <= 0.5) i->HP -= agg_of_tower;
    }else fire(a);
}
void print(){
    printf("%ld\n", ant.size());
    for(auto i : ant) printf("%d %d %d %d %d\n", i.years, i.Lv, i.HP, i.pos.x, i.pos.y);
}
void start_game(){
    for(now_tim = 1; now_tim <= end_tim; ++now_tim){
        if(ant.size() < 6 && !vis[0][0]) get_new_ant(); 
        for(auto i : ant) map[i.pos.x][i.pos.y] += i.target ? 5 : 2;
        for(vec_it i = ant.begin(); i != ant.end(); ++i) mov(i); 
        for(vec_it i = ant.begin(); i != ant.end(); ++i){
            if(find_target() == ant.end() && i->pos == Point(n, m)){
                i->HP = std::min(init_HP(*i), i->HP + init_HP(*i) / 2);
                i->target = true;
            }
        }
        vec_it target = find_target();
        if(target != ant.end()) for(int i = 1; i <= sum_of_tower; ++i) fire(tower[i], target);
        else                    for(int i = 1; i <= sum_of_tower; ++i) fire(tower[i]);
        bool upd = true;
        while(upd){
            upd = false;
            for(vec_it i = ant.begin(); i != ant.end(); ++i) if(i->HP < 0){
                vis[i->pos.x][i->pos.y] = false;
                ant.erase(i);
                upd = true;
                break;
            }
        }
        target = find_target();
        if(target != ant.end() && target->pos == Point(0, 0)){ printf("Game over after %d seconds\n", now_tim); break; }
        for(int i = 0; i <= n; ++i) for(int j = 0; j <= m; ++j) if(map[i][j]) --map[i][j];
        for(vec_it i = ant.begin(); i != ant.end(); ++i) ++i->years;
    }
    if(now_tim > end_tim) printf("The game is going on\n");
    print();
}
int main(){
    scanf("%d%d%d%d%d", &n, &m, &sum_of_tower, &agg_of_tower, &r_of_tower);
    for(int i = 1; i <= sum_of_tower; ++i){
        int x, y;
        scanf("%d%d", &x, &y);
        vis[x][y] = true;
        tower[i] = Point(x, y);
    }
    scanf("%d", &end_tim);
    start_game();

    return 0;
}

所以我昨天为什么会去写 La_Pluma 的数学呢

标签:const,蚂蚁,Point,double,一天,pos,Vec,operator,结束
From: https://www.cnblogs.com/Silver-ash/p/16774335.html

相关文章

  • linux 如何查找并结束僵尸进程
    当时用top命令查看时,发现zombie数字不是0,就说明有僵尸进程了。寻找僵尸进程ps-ef|grep杀掉该进程kill-9[pid]......
  • python 默认主进程结束前,不会主动结束子进程
    1#coding=utf82importmultiprocessing3importtime456defprocess(name):7whileTrue:8print('进程名:{}正在运行...'.format(name)......
  • 暑假集训二[LCIS,平凡的函数,那一天她离我而去,矩形]
    暑假集训2LCIS首先我赛时打了个\(n^{4}\)的暴力,因为一个转移的地方忘记加max了,然后拿了\(70\),本来以为改改也就T了结果它加了个\(max\)就\(A\)了.....这数据也是没谁......
  • 算法练习-第十一天【栈与队列】
    栈与队列232.用栈实现队列参考:代码随想录思路一道模拟题,不涉及到算法部分。如果想用栈来实现队列,至少需要2个栈,一个输入栈一个输出栈。在进行push操作时,将数据放入到......
  • C语言每日一题——第十一天
    第十一天还记得在第三天写的斐波那契数列程序吗?小明最初想用这个函数作为随机数生成器的。今天,小明决定重新拾起这个函数,用于生成随机数……输入程序在运行时通过getcha......
  • ssm第一天学习
    SSM·IOC·AOP初识Spring:Spring全家桶SpringFramework底层框架,设计性框架SpringBoot加速开发,提高开发速度SpringCloud分布式开发 SpringFramework系统......
  • 写在特别的国庆,最后一天
    近一月以来,严重精神内耗,整个人变的恍惚,犹豫不定,一度陷入自我怀疑,事情的起因是这样的:该死的情怀农村出来的娃娃是不是都想着报效祖国,我不知道这样的预期是不是正确,但我却......
  • 蚂蚁金服终端实验室演进之路
    作者:周力(问瑾)0.背景作为国民级App,支付宝客户端需要为亿级用户提供多元化的服务,因此应用的稳定性与可靠性面临巨大的挑战,需要不断地完善和优化。今天,让我们站在服务质量的......
  • 结束与开始
    我很少在博客上闲聊,除了技术文章,我觉得说些什么都显得矫情。毕竟,你的问题,大多数人都经历过,有什么好逼逼的。所以我从未在这里表达过个人的情绪或者生活的状态。只是分......
  • 第一天博客纪念
    第一日博客纪念今天是第一天使用博客园,故发此随笔以作纪念。没有内容也不行,所以这篇随笔就解决一个小问题吧。问题:去掉数组中的重复项(限javascript)vararr=[1,1,......