[挑战记录][ZJOI2008]杀蚂蚁

自从有大佬 \(2h\) \(1A\) 杀蚂蚁后,我这个蒟蒻就对这道题充满了向往
于是今天我要挑战一下!
总有地上的的生灵,敢于直面神灵的威光

20221009 10:00

准点开始答题

10:45

被 SMTwy 拉去改宣誓词(悲

11:15

回来了

11:30

去吃火锅(大喜)

14:30

完成了数学部分(计算点到直线距离)
共计用时:1h30min

15:25

完成了蚂蚁行动的部分
用时 2h25min
果然我还是太菜了,两个小时写完的是什么神仙啊

16:33

写完了!开始调弑
\(\cdots\) 10分
用时 3h33min (还挺整)

16:45

30 分,去开大会

18:40

滚回来写

19:36

过了
总计用时(四舍五入)约为 4h45min
交了11遍
果然这就是人和神之间的差距吗!!!

点击查看代码
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<set>
#include<cmath>
#define int long long
#define WR WinterRain
using namespace std;
const int WR=101,INF=1099511627776;
const double eps=1e-12;
pair<int,int>dir[10];
struct Point{
    double x,y;
    Point(double _x,double _y){
        x=_x,y=_y;
    }
    Point(){}
    Point operator+(const Point &b)const{
        Point res;
        res=Point(x+b.x,y+b.y);
        return res;
    }
    Point operator-(const Point &b)const{
        Point res;
        res=Point(x-b.x,y-b.y);
        return res;
    }
};
struct Map{
    int pheromone;
    bool vis;
}mp[WR][WR];
struct Turrent{
    int goal;
    int x,y;
}tur[WR*WR];
struct Ant{
    int posx,posy,prex,prey;
    int age,level,HP,limHP;
    bool cake,dead;
}ant[WR*WR*WR];
int n,m;
int s,d,r;
int t;
int sumant,posant;
int st=1,tag;
bool TakenCake;
int read(){
    int s=0,w=1;
    char ch=getchar();
    while(ch>'9'||ch<'0'){
        if(ch=='-') w=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9'){
        s=(s<<3)+(s<<1)+ch-'0';
        ch=getchar();
    }
    return s*w;
}
int sgn(double x){
    if(fabs(x)<=eps) return 0;
    else return (x>eps?1:-1);
}
double dot(Point a,Point b){
    return a.x*b.x+a.y*b.y;
}
double cross(Point a,Point b){
    return a.x*b.y-a.y*b.x;
}
double lenth(Point a){
    return sqrt(dot(a,a));
}
double get_slope(Point a){
    return a.y/a.x;
}
double getdis_segment(Point p,Point a,Point b){
    Point vec1,vec2,vec3;
    vec1=b-a,vec2=p-a,vec3=p-b;
//    printf("%.6lf %.6lf\n",vec1.x,vec1.y);
//    printf("%.6lf %.6lf\n",vec2.x,vec2.y);
//    printf("%.6lf %.6lf\n",vec3.x,vec3.y);
    if(sgn(dot(vec1,vec2))<0) return lenth(vec2);
    if(sgn(dot(vec1,vec3))>0) return lenth(vec3);
    return fabs(cross(vec1,vec2)/lenth(vec1));
}
double getdis_point(int x1,int y1,int x2,int y2){
    return sqrt((double)((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)));
}
double quick_pow(double a,int b){
    double base=a,res=1.0;
    while(b){
        if(b&1) res*=base;
        base*=base;
        b>>=1;
    }
    return res;
}
void Ants_Born(){
    if(posant>=6||mp[0][0].vis) return;
    posant++,sumant++;
    mp[0][0].vis=true;
    ant[sumant].level=(sumant-1)/6+1;
    ant[sumant].HP=ant[sumant].limHP=floor(4.0*quick_pow(1.1,ant[sumant].level));
    ant[sumant].dead=ant[sumant].cake=false;
    ant[sumant].age=ant[sumant].posx=ant[sumant].posy=0;
    ant[sumant].prex=ant[sumant].prey=INF;
}
void Drop_Pheromone(){
    for(int i=st;i<=sumant;i++){
        if(ant[i].dead) continue;
        if(!ant[i].cake) mp[ant[i].posx][ant[i].posy].pheromone+=2;
        else mp[ant[i].posx][ant[i].posy].pheromone+=5;
    }
}
void Ants_Move(){
    for(int i=st;i<=sumant;i++){
        if(ant[i].dead) continue;
        int nxtx,nxty,maxph=-1,direc=-1;
        for(int j=1;j<=4;j++){
            nxtx=ant[i].posx+dir[j].first,nxty=ant[i].posy+dir[j].second;
            if(mp[nxtx][nxty].vis||nxtx<0||nxty<0||nxtx>n||nxty>m) continue;
            if(nxtx==ant[i].prex&&nxty==ant[i].prey) continue;
            if(maxph<mp[nxtx][nxty].pheromone){
                maxph=mp[nxtx][nxty].pheromone;
                direc=j;
            }
        }
        if((ant[i].age+1)%5==0&&direc!=-1){
            for(int j=1;j<=4;j++){
                int newdir=(direc-j+3)%4+1;
                nxtx=ant[i].posx+dir[newdir].first,nxty=ant[i].posy+dir[newdir].second;
                if(mp[nxtx][nxty].vis||nxtx<0||nxty<0||nxtx>n||nxty>m) continue;
//                printf("Ant %lld is in crazy mod,turning to (%lld,%lld),pre is (%lld,%ld)\n",i,nxtx,nxty,ant[i].prex,ant[i].prey);
                if(nxtx==ant[i].prex&&nxty==ant[i].prey) continue;
                direc=newdir;break;
            }
        }
        ant[i].prex=ant[i].posx,ant[i].prey=ant[i].posy;
        if(direc==-1) continue;
        mp[ant[i].posx][ant[i].posy].vis=false;
        ant[i].posx+=dir[direc].first,ant[i].posy+=dir[direc].second;
        mp[ant[i].posx][ant[i].posy].vis=true;
//        printf("Ant %lld move from (%lld,%lld) to (%lld,%lld)\n",i,ant[i].prex,ant[i].prey,ant[i].posx,ant[i].posy);
    }
}
void Check_Cake(){
    if(TakenCake) return;
    for(int i=st;i<=sumant;i++){
        if(ant[i].dead) continue;
        if(ant[i].posx==n&&ant[i].posy==m){
            tag=i,TakenCake=true,ant[i].cake=true;
            ant[i].HP=min(ant[i].HP+(ant[i].limHP>>1),ant[i].limHP);
            return;
        }
    }
}
void Turrent_Fire(){
    for(int i=1;i<=s;i++){
        double dis_to_tag;
        if(TakenCake) dis_to_tag=getdis_point(tur[i].x,tur[i].y,ant[tag].posx,ant[tag].posy);
        if(!TakenCake||dis_to_tag-(double)r>eps){
            double curdis,mindis=INF;
            for(int j=st;j<=sumant;j++){
                if(ant[j].dead) continue;
                curdis=getdis_point(tur[i].x,tur[i].y,ant[j].posx,ant[j].posy);
                if(curdis<mindis){
                    mindis=curdis;
                    tur[i].goal=j;
                }
            }
            if(mindis-(double)r>eps){
                tur[i].goal=0;
                continue;
            }
            ant[tur[i].goal].HP-=d;
//            printf("%lld's goal is %lld\n",i,tur[i].goal);
//            printf("Ouch!Ant %lld dropped %lld HP\n",tur[i].goal,d);
        }else{
            tur[i].goal=tag;
            Point b=Point(tur[i].x,tur[i].y),a=Point(ant[tag].posx,ant[tag].posy);
            for(int j=st;j<=sumant;j++){
                if(ant[j].dead) continue;
                if(ant[j].cake){
                    ant[j].HP-=d;
//                    printf("Ouch!Ant %lld dropped %lld HP(with cake)\n",j,d);
                    continue;
                }
                Point p=Point(ant[j].posx,ant[j].posy);
                double dis_to_tur=getdis_segment(p,a,b);
//                printf("%lld's dis to segment is %.6lf\n",j,dis_to_tur);
                if(dis_to_tur-0.5<eps) ant[j].HP-=d;
//                printf("Ouch!Ant %lld dropped %lld HP(not offensive)\n",j,d);
            } 
        } 
    }
}
void Clear_Battlefield(){
    for(int i=st;i<=sumant;i++){
//        printf("Ant %lld's blood is %lld\n",i,ant[i].HP);
        if(ant[i].dead||ant[i].HP>=0) continue;
        posant--;
        mp[ant[i].posx][ant[i].posy].vis=false;
        ant[i].dead=true;
        if(ant[i].cake) tag=TakenCake=ant[i].cake=0;
//        printf("Ant %lld dead\n",i);
    }
}
bool Check_Win(){
    if(!TakenCake) return false;
    for(int i=st;i<=sumant;i++){
        if((!ant[i].dead)&&(!ant[i].posx)&&(!ant[i].posy)&&ant[i].cake) return true;
    }
    return false;
}
void Ants_Grow(){
    for(int i=st;i<=sumant;i++){
        if(ant[i].dead) continue;
        ant[i].age++;
    }
}
void Pheromone_Disapper(){
    for(int i=0;i<=n;i++){
        for(int j=0;j<=m;j++){
            if(mp[i][j].pheromone) mp[i][j].pheromone--;
        }
    }
}
void print(){
    printf("%lld\n",posant);
//    printf("sum=%lld\n",sumant);
//    for(int i=1;i<=sumant;i++) printf("No.%lld ant is %d\n",i,ant[i].dead);
    for(int i=st;i<=sumant;i++){
        if(ant[i].dead) continue;
        printf("%lld %lld %lld %lld %lld\n",ant[i].age,ant[i].level,ant[i].HP,ant[i].posx,ant[i].posy);
    }
}
signed main(){
//    freopen("test.in","r",stdin);
//    freopen("P2586.out","w",stdout);
    dir[1]=make_pair(0,1),dir[2]=make_pair(1,0);
    dir[3]=make_pair(0,-1),dir[4]=make_pair(-1,0);
    n=read(),m=read(),s=read(),d=read(),r=read();
    for(int i=1;i<=s;i++) tur[i].x=read(),tur[i].y=read(),mp[tur[i].x][tur[i].y].vis=true;
    t=read();
    for(int i=1;i<=t;i++){
//        printf("%lld\n",i);
        Ants_Born();
        Drop_Pheromone();
        Ants_Move();
        Check_Cake();
        Turrent_Fire();
        Clear_Battlefield();
        if(Check_Win()){
            printf("Game over after %lld seconds\n",i);
            print();
            return 0;
        }
        Ants_Grow();
        Pheromone_Disapper();
        while(ant[st].dead) st++;
    }
    printf("The game is going on\n");
    print();
    return 0;
}
posted @ 2022-10-09 19:39  冬天丶的雨  阅读(47)  评论(0编辑  收藏  举报
Live2D