bzoj1033: [ZJOI2008]杀蚂蚁antbuster

传送门
炒鸡无敌大模拟。
就是打打太麻烦。
我不会给你讲我打错了game

#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int n,m,s,turd,r,T,born,getcake;
int in[11][11],mp[11][11];
const int c[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
struct ant{
    int lev,hp,age,x,y,lx,ly,mx;
    bool live,cake;
}a[11];
struct point{int x,y;}tur[31];
struct line{point a,b;}l;
point sub(point a,point b){
    return (point){a.x-b.x,a.y-b.y};
}
int cmul(point a,point b){
    return a.x*b.y-a.y*b.x;
}
int turn(point a,point b,point c){
    return cmul(sub(b,a),sub(c,a)); 
}
int sqr(int x){
    return x*x;
}
double dis(int x1,int y1,int x2,int y2){
    return sqrt(sqr(x1-x2)+sqr(y1-y2));
}
int dis2(int x,int y){
    return sqr(tur[x].x-a[y].x)+sqr(tur[x].y-a[y].y);
}
double dis(int x,int y){
    return sqrt(dis2(x,y));
}
bool cmp(ant a,ant b){
    return a.age>b.age;
}
void bornant(int k){
    int l=born/6+1;
    a[k].lev=l;
    a[k].hp=a[k].mx=int(4*pow(1.1,l));
    a[k].age=0;
    a[k].live=1;
    a[k].x=a[k].y=a[k].lx=a[k].ly=0;
    mp[0][0]=1;
    born++;
}
bool jud(int x,int y,int lx,int ly){
    if (mp[x][y]||x<0||y<0||x>n||y>m) return 0;
    if (x==lx&&y==ly) return 0;
    return 1;
}
void move(int k,int dir){
    int x=a[k].x,y=a[k].y;
    if (dir==-1){
        a[k].lx=x;
        a[k].ly=y;
        return;
    }
    int nx=x+c[dir][0],ny=y+c[dir][1];
    mp[x][y]=0; mp[nx][ny]=1;
    a[k].lx=x; a[k].ly=y;
    a[k].x=nx; a[k].y=ny;
}
void spmove(int k,int dir){
    for (int i=(dir+3)%4;;i=(i+3)%4){
        int nx=a[k].x+c[i][0];
        int ny=a[k].y+c[i][1];
        if (jud(nx,ny,a[k].lx,a[k].ly)){
            move(k,i);
            return;
        }
    }
}
void premove(int k){
    int x=a[k].x,y=a[k].y;
    int lx=a[k].lx,ly=a[k].ly;
    int mx=-0x3f3f3f3f,dir=-1;
    for (int i=0;i<4;i++){
        int nx=x+c[i][0],ny=y+c[i][1];
        if (jud(nx,ny,lx,ly)&&mx<in[nx][ny])
            mx=in[nx][ny];
    }
    for (int i=0;i<4;i++){
        int nx=x+c[i][0],ny=y+c[i][1];
        if (jud(nx,ny,lx,ly)&&mx==in[nx][ny]){
            dir=i; break;
        }
    }
    if (a[k].age%5!=4||dir==-1) move(k,dir);
    else spmove(k,dir);
}
bool cross(int x,int y){
    double d=dis(l.a.x,l.a.y,l.b.x,l.b.y);
    if (x==l.a.x&&y==l.a.y||x==l.b.x&&y==l.b.y) return 1;
    int x1=min(l.a.x,l.b.x),x2=max(l.a.x,l.b.x);
    int y1=min(l.a.y,l.b.y),y2=max(l.a.y,l.b.y);
    if (x<x1||x>x2||y<y1||y>y2) return 0;
    point p; p.x=x; p.y=y;
    if (fabs(turn(l.a,l.b,p))/d<=0.5) return 1;
    return 0;
}
void attack(int k){
    int tmp=-1,dis=0x3f3f3f3f;
    for (int i=1;i<=6;i++)
        if (a[i].live){
            int d=dis2(k,i);
            if (d<=r*r){
                if (a[i].cake) tmp=i;
                else if (!a[tmp].cake&&d<dis){
                    dis=d; tmp=i;
                }
            }
        }
    if (tmp==-1) return;
    l.a=tur[k]; l.b.x=a[tmp].x; l.b.y=a[tmp].y;
    for (int i=1;i<=6;i++)
        if (a[i].live&&cross(a[i].x,a[i].y))
            a[i].hp-=turd;
}
bool solve(int t){
    if (!mp[0][0])
        for (int i=1;i<=6;i++)
            if (!a[i].live){
                bornant(i);
                break;
            }
    sort(a+1,a+7,cmp);
    for (int i=1;i<=6;i++)
        if (a[i].live){
            int x=a[i].x,y=a[i].y;
            if (a[i].cake) in[x][y]+=5;
            else in[x][y]+=2;
        }
    for (int i=1;i<=6;i++)
        if (a[i].live) premove(i);
    if (!getcake)
        for (int i=1;i<=6;i++)
            if (a[i].live&&a[i].x==n&&a[i].y==m){
                a[i].cake=getcake=1;
                a[i].hp=min(a[i].mx,a[i].hp+a[i].mx/2);
            }
    for (int i=1;i<=s;i++) attack(i);
    for (int i=1;i<=6;i++)
        if (a[i].live&&a[i].hp<0){
            mp[a[i].x][a[i].y]=0;
            a[i].live=0;
            if (a[i].cake) a[i].cake=getcake=0;
        }
    if (getcake)
        for (int i=1;i<=6;i++)
            if (a[i].live&&a[i].cake&&a[i].x==0&&a[i].y==0)
                return 1;
    for (int i=0;i<=n;i++)
        for (int j=0;j<=m;j++)
            if (in[i][j]>0) in[i][j]--;
    for (int i=1;i<=6;i++)
        if (a[i].live) a[i].age++;
    return 0;
}
void init(){
    scanf("%d%d",&n,&m);
    scanf("%d%d%d",&s,&turd,&r);
    for (int i=1;i<=s;i++){
        scanf("%d%d",&tur[i].x,&tur[i].y);
        mp[tur[i].x][tur[i].y]=1;
    }
    scanf("%d",&T);
}
void print(){
    int cot=0;
    sort(a+1,a+7,cmp);
    for (int i=1;i<=6;i++)
        if (a[i].live) cot++;
    printf("%d\n",cot);
    for (int i=1;i<=6;i++)
        if (a[i].live)
            printf("%d %d %d %d %d\n",a[i].age,a[i].lev,a[i].hp,a[i].x,a[i].y);
}
int main(){
    init();
    for (int i=1;i<=T;i++)
        if (solve(i)){
            printf("Game over after %d seconds\n",i);
            print();
            return 0;
        }
    printf("The game is going on\n");
    print();
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值