BZOJ 1033 [ZJOI2008]杀蚂蚁antbuster 模拟

Warning!

本题解与代码没有任何参考意义

题目大意:杀蚂蚁。

题目分析:小心别让蚂蚁杀了。
这里写图片描述
请欣赏我又长又屎的代码

///Enter the Game
void Run_Game();
main() {Run_Game();}



///Dim Basic Object
#include <cstdio>
#include <cmath>
using namespace std;
inline int min(int x,int y) { return x < y ? x : y; }
inline int max(int x,int y) { return x > y ? x : y; }
inline int sq(int x) { return x*x; }
class Point {
private:
    int x, y;
public:
    Point(int _x=0, int _y=0): x(_x), y(_y) {}
    bool operator == (const Point& rhs) const { return x==rhs.x && y==rhs.y; }
    Point operator + (const Point& rhs) const { return Point(x+rhs.x,y+rhs.y); }
    Point operator - (const Point& rhs) const { return Point(x-rhs.x,y-rhs.y); }
    int operator | (const Point& rhs) const { return sq(x-rhs.x)+sq(y-rhs.y); }
    int operator ^ (const Point &rhs) const { return x*rhs.x+y*rhs.y; }
    int operator * (const Point& rhs) const { return x*rhs.y-y*rhs.x; }
    void scan() {
        scanf("%d%d", &x, &y);
        return ;
    }
    void print() {
        printf("%d %d",x,y);
        return ;
    }
    int get_x() {
        return x;
    }
    int get_y() {
        return y;
    }
};
const Point dir[4]={Point(0,1),Point(1,0),Point(0,-1),Point(-1,0)};
class Maps {
private:
    int n,m,Cake_pos,Map[10][10];
    bool jud[10][10];
public:
    void scan() {
        scanf("%d%d",&n,&m);
        Cake_pos=-1;
        return ;
    }
    void print() {
        for(int i=0;i<=n;i++) {
            for(int j=0;j<=m;j++)
                printf("%3d ",jud[i][j] ? -1 : Map[i][j]);
            printf("\n");
        }
        return ;
    }
    int get_cakepos() {
        return Cake_pos;
    }
    Point get_CakeOriginPos() {
        return Point(n,m);
    }
    int Info(Point o) {
        int x=o.get_x(),y=o.get_y();
        if(jud[x][y]) return -1;
        return Map[x][y];
    }
    void change_cakepos(int x) {
        Cake_pos=x;
        return ;
    }
    bool out_of_map(Point o) {
        int x=o.get_x(),y=o.get_y();
        if(x<0 || x>n || y<0 || y>m) return true;
        return false;
    }
    void add(Point o,int delta) {
        int x=o.get_x(), y=o.get_y();
        Map[x][y]+=delta;
        return ;
    }
    void rev(Point o) {
        int x=o.get_x(), y=o.get_y();
        jud[x][y]=!jud[x][y];
        return ;
    }
    void update() {
        for(int i=0;i<=n;i++)
            for(int j=0;j<=m;j++)
                Map[i][j]=max(0,Map[i][j]-1);
        return ;
    }
}maps;


///Dim Object
class Ants {
private:
    int Ant_amount,Ant_total;
    struct Ant {
        int age, birth, hp, level, hp_limit;
        Point pos,last_pos;
        bool cake;
        Ant(int number=0) {
            last_pos=pos=Point(0,0);
            maps.rev(pos);
            age=0;
            cake=false;
            level=number/6+1;
            hp=hp_limit=int(4.0*pow(1.1,double(level)));
        }
        void Move() {
            int max_info=-1,to_dir=-1;
            for(int i=0;i<4;i++) {
                Point to=pos+dir[i];
                if(to==last_pos || maps.out_of_map(to) || maps.Info(to)==-1) continue;
                if(maps.Info(to)>max_info) max_info=maps.Info(to),to_dir=i;
            }
            if(to_dir==-1) {
                last_pos=pos;
                return ;
            }
            if(age%5==4)
                for(int i=0;i<4;i++) {
                    --to_dir;
                    if(to_dir<0) to_dir+=4;
                    Point to=pos+dir[to_dir];
                    if(to==last_pos || maps.out_of_map(to) || maps.Info(to)==-1) continue;
                    break;
                }
            last_pos=pos;
            pos=pos+dir[to_dir];
            maps.rev(last_pos);
            maps.rev(pos);
            return ;
        }
        void LeaveInfo() {
            maps.add(pos,(cake ? 5 : 2));
            return ;
        }
        void print() {
            printf("%d %d %d ",age,level,hp);
            pos.print();
            printf("\n");
            return ;
        }
    }ant[10];
    void Born() {
        if(Ant_amount>5 || maps.Info(Point(0,0))==-1) return ;
        ant[++Ant_amount]=Ant(Ant_total++);
        return ;
    }
    void Leave_Infomation() {
        for(int i=1;i<=Ant_amount;i++) ant[i].LeaveInfo();
        return ;
    }
    void Move() {
        for(int i=1;i<=Ant_amount;i++) ant[i].Move();
        return ;
    }
    void to_get_Cake() {
        int Cake_pos=maps.get_cakepos();
        if(Cake_pos!=-1) return ;
        for(int i=1;i<=Ant_amount;i++)
            if(ant[i].pos==maps.get_CakeOriginPos()) {
                maps.change_cakepos(i);
                ant[i].cake=true;
                ant[i].hp=min(ant[i].hp_limit,ant[i].hp+ant[i].hp_limit/2);
                return ;
            }
        return ;
    }
public:
    Point get_antpos(int x) {
        return ant[x].pos;
    }
    int get_Antamount() {
        return Ant_amount;
    }
    int get_Anttotal() {
        return Ant_total;
    }
    bool get_cake() {
        int Cake_pos=maps.get_cakepos();
        if(Cake_pos==-1) return false;
        if(ant[Cake_pos].pos==Point(0,0)) return true;
        return false;
    }
    void make_damage(int i,int x) {
        ant[i].hp-=x;
        return ;
    }
    void action() {
        Born();
        Leave_Infomation();
        Move();
        to_get_Cake();
        return ;
    }
    void Update() {
        int tot=0;
        for(int i=1;i<=Ant_amount;i++)
            if(ant[i].hp>=0) ant[++tot]=ant[i];
            else maps.rev(ant[i].pos);
        Ant_amount=tot;
        int Cake_pos=-1;
        for(int i=1;i<=Ant_amount;i++)
            if(ant[i].cake)
                Cake_pos=i;
        maps.change_cakepos(Cake_pos);
        return ;
    }
    void Grow() {
        for(int i=1;i<=Ant_amount;i++) ant[i].age++;
        return ;
    }
    void print_Infomation() {
        printf("%d\n",Ant_amount);
        for(int i=1;i<=Ant_amount;i++) ant[i].print();
        return ;
    }
}ants;


class Towers {
private:
    int Tower_amount, Tower_damage, Tower_range;
    struct Tower {
        Point pos;
        int damage,range;
        void scan(int _damage,int _range) {
            pos.scan();
            maps.rev(pos);
            damage=_damage;
            range=_range;
            return ;
        }
        bool Cross(Point x,Point y) {
            if((x|pos)>sq(range)) return false;
            int dot=(x-pos)^(y-pos);
            int len=pos|x;
            if(dot<0) return (pos|y)*4<=1;
            if(dot>len) return (pos|y)*4<=1;
            int dist=(pos-y)*(x-y);
            return dist*dist*4<=len;
        }
        int get_target() {
            int min_dist=sq(range)+1,target=-1,Ant_amount=ants.get_Antamount(),Cake_pos=maps.get_cakepos();
            for(int i=1;i<=Ant_amount;i++) {
                Point antpos=ants.get_antpos(i);
                int dist=pos|antpos;
                if(dist<=sq(range)) {
                    if(i==Cake_pos) return i;
                    if(dist<min_dist) min_dist=dist, target=i;
                }
            }
            return target;
        }
        void Shoot() {
            int target=get_target();
            if(target==-1) return ;
            int Ant_amount=ants.get_Antamount();
            for(int i=1;i<=Ant_amount;i++)
                if(Cross(ants.get_antpos(target),ants.get_antpos(i)))
                    ants.make_damage(i,damage);
            return ;
        }
    }tower[25];
    void Attack() {
        for(int i=1;i<=Tower_amount;i++) tower[i].Shoot();
        ants.Update();
        return ;
    }
public:
    void scan() {
        scanf("%d%d%d",&Tower_amount,&Tower_damage,&Tower_range);
        for(int i=1;i<=Tower_amount;i++) tower[i].scan(Tower_damage,Tower_range);
        return ;
    }
    void action() {
        Attack();
        return ;
    }
}towers;



///Run the Game
int T;
void Start_Game();
int Play_Game();
void End_Game(const int);
void Run_Game() {
    Start_Game();
    const int result=Play_Game();
    End_Game(result);
    return ;
}
void Start_Game() {
    maps.scan();
    towers.scan();
    scanf("%d",&T);
    return ;
}
int Play_Game() {
    int tim;
    for(tim=1;tim<=T;tim++) {
        ants.action();
        towers.action();
        if(ants.get_cake()) break;
        maps.update();
        ants.Grow();
    }
    return tim;
}
void End_Game(const int result) {
    if(result<=T) printf("Game over after %d seconds\n",result);
    else printf("The game is going on\n");
    ants.print_Infomation();
    return ;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值