bzoj 1033【ZJOI2008】杀蚂蚁

来源:互联网 发布:天地通软件 编辑:程序博客网 时间:2024/05/16 08:08

题目大意:
我已经想到一个绝妙的办法把这2000字的题面解释清楚,可惜这里空白的地方太小,我写不下了……
这里写图片描述

题目分析:
无言独上西楼,月如钩,寂寞梧桐深院锁清秋。
这里写图片描述

代码如下:

#include <cstdio>#include <iostream>#include <cmath>using namespace std;int n,m,S,D,R,T;int a[10][10];bool v[10][10];int Cake=-1;int Time_Stamp=1,Ant_Stamp;int ant_number;struct point{    int x,y;    point(int x=0,int y=0):x(x),y(y){}    point operator + (const point &c) { return point(x+c.x,y+c.y); }    point operator - (const point &c) { return point(x-c.x,y-c.y); }    bool operator == (const point &c) { return x==c.x && y==c.y; }    int operator | (const point &c) { return (x-c.x)*(x-c.x)+(y-c.y)*(y-c.y); }    int operator * (const point &c) { return x*c.y-y*c.x; }    int operator ^ (const point &c) { return x*c.x+y*c.y; }     bool judge()    {        if(x<0 || x>n) return false;        if(y<0 || y>m) return false;        return true;    }}tower[30];const point dir[4]={point(0,1),point(1,0),point(0,-1),point(-1,0)};struct ant{    point pos,last;    int HP,age,limit,level;    bool cake;    ant()    {        pos=last=point(0,0);        age=0; cake=false;        level=Ant_Stamp/6+1;        HP=limit=int(4.0*pow(1.1,double(level)));    }}e[10];void read(){    cin>>n>>m;    cin>>S>>D>>R;    for(int i=1;i<=S;i++)    {        cin>>tower[i].x>>tower[i].y;        v[tower[i].x][tower[i].y]=true;    }    cin>>T;}void ant_bear(){    if(ant_number>=6) return;    if(v[0][0]) return;    e[++ant_number]=ant();    v[0][0]=true;    ++Ant_Stamp;    return;}void Left_information(){    for(int i=1;i<=ant_number;i++)          a[e[i].pos.x][e[i].pos.y]+=e[i].cake?5:2;    return;}void ant_move(){    for(int i=1;i<=ant_number;i++)    {        int tmp=-1,to=-1;        for(int j=0;j<4;j++)        {            point aid=e[i].pos+dir[j];            if(aid==e[i].last) continue;            if(!aid.judge()) continue;            if(v[aid.x][aid.y]) continue;            if(a[aid.x][aid.y]>tmp) tmp=a[aid.x][aid.y],to=j;        }        if(to==-1)        {            e[i].last=e[i].pos;            continue;        }        if(e[i].age%5==4)        {            while(true)            {                to=(to+3)%4;                point aid=e[i].pos+dir[to];                if(aid==e[i].last) continue;                if(!aid.judge()) continue;                if(v[aid.x][aid.y]) continue;                break;            }        }        e[i].last=e[i].pos;        e[i].pos=e[i].pos+dir[to];        v[e[i].last.x][e[i].last.y]=false;        v[e[i].pos.x][e[i].pos.y]=true;    }}void get_cake(){    if(Cake!=-1) return;    for(int i=1;i<=ant_number;i++)    {        if(e[i].pos==point(n,m))        {            e[i].cake=true;            e[i].HP=min(e[i].limit,e[i].HP+e[i].limit/2);            Cake=i;            return;        }    }    return;}int get_target(point c){    int tmp=R*R+1,to=-1;    for(int i=1;i<=ant_number;i++)    {        int dis=c|e[i].pos;        if(dis<=R*R)        {            if(e[i].cake) return i;            if(dis<tmp) tmp=dis,to=i;        }    }    return to;}bool Cross(point turret,point target,point c){    if((target|turret)>R*R) return false;    int dot=(target-turret)^(c-turret);    int len=turret|target;    if(dot<0) return (turret|c)*4<=1;    if(dot>len) return (target|c)*4<=1;    int dis=(turret-c)*(target-c);    return dis*dis*4<=len;}void shoots(){    for(int i=1;i<=S;i++)    {        int aim=get_target(tower[i]);        if(aim==-1) continue;        for(int j=1;j<=ant_number;j++)            if(Cross(tower[i],e[aim].pos,e[j].pos)) e[j].HP-=D;    }    int tmp=0;    for(int i=1;i<=ant_number;i++)    {        if(e[i].HP>=0) e[++tmp]=e[i];        else v[e[i].pos.x][e[i].pos.y]=false;    }    ant_number=tmp;    Cake=-1;    for(int i=1;i<=ant_number;i++)        if(e[i].cake) Cake=i;    return;}void seconds_over(){    for(int i=0;i<=n;i++)        for(int j=0;j<=m;j++)            a[i][j]=max(a[i][j]-1,0);    for(int i=1;i<=ant_number;i++)        e[i].age++;    return;}void print(bool judge){    if(judge) cout<<"The game is going on"<<endl;    else    cout<<"Game over after "<<Time_Stamp<<" seconds"<<endl;    cout<<ant_number<<endl;    for(int i=1;i<=ant_number;i++)    {        cout<<e[i].age<<" "<<e[i].level<<" "<<e[i].HP<<" ";        cout<<e[i].pos.x<<" "<<e[i].pos.y<<endl;    }    return;}int main(){    read();    while(Time_Stamp<=T)    {        ant_bear();        Left_information();        ant_move();        get_cake();        shoots();        if(Cake!=-1 && e[Cake].pos==point(0,0))        {            print(false);            return 0;        }        seconds_over();        Time_Stamp++;    }    print(true);    return 0;}
1 0