ZOJ 3698 Carrot Fantasy(搜索大模拟)

题目地址:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3698

题意自己google翻译。

明显的给出了monster,tower各个属性,这肯定是要建类。

不过要注意的细节是移动方式。

dir[8][2]= {0,1,0,-1,1,0,-1,0,1,1,1,-1,-1,1,-1,-1}

到了搜索路径的时候实际作用的其实是dir[][](0~3).

queue注意是x,y方向搜索。

其他一些判重之类没什么好讲。中等水题,需要的是无尽的耐心和细心。享受孤独,以及TLE剪纸之后WA的心情(笑)fascinating!

AC代码:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<string>
#include<algorithm>
#include<queue>
#include<utility>
using namespace std;
#define ll long long
char mm[60][60];
//int dir[8][2]= {0,1,0,-1,1,0,-1,0,1,1,1,-1,-1,1,-1,-1};
int dx[8]={0,0,1,-1,1,1,-1,-1};
int dy[8]={1,-1,0,0,1,-1,1,-1};
int sx,sy,tx,ty,tott,totm,totmm;
int n,m,Hp,tot,to[60][60][2],dis[60][60];
struct monster
{
    int x,y,hp,t;
    bool need,ice;
    void born(int a)
    {
        x=sx;
        y=sy;
        t=a;
        hp=Hp;
        need=ice=0;
    }
    void move()
    {
        if(need)hp-=10;
        if(ice)
        {
            ice=0;
            return;
        }
        int nx=to[x][y][0],ny=to[x][y][1];
        x=nx;
        y=ny;
    }
    friend bool operator < (monster m1,monster m2)
    {
        if(m1.hp>0&&m2.hp>0)
        {
            if(m1.x==m2.x&&m1.y==m2.y)
            {
                return m1.t<m2.t;
            }
            return dis[m1.x][m1.y]<dis[m2.x][m2.y];
        }
        return m1.hp>m2.hp;
    }
} mon[60],tmm[60];
struct tower
{
    int x,y;
    char typ;
    tower(int a,int b,char ty)
    {
        x=a;
        y=b;
        typ=ty;
    }
    tower(){}
    bool in(int mx,int my)
    {
        for(int i=0; i<8; i++)
        {
            int nx=x+dx[i];
            int ny=y+dy[i];
            if(nx==mx&&ny==my)return 1;
        }
        return 0;
    }
    void attack()
    {
        if(typ=='B')
        {
            for(int i=0; i<totm; i++)
                if(in(mon[i].x,mon[i].y))
                {
                    mon[i].hp-=10;
                    break;
                }
        }
        if(typ=='F')
        {
            for(int i=0; i<totm; i++)
                if(in(mon[i].x,mon[i].y))
                {
                    mon[i].hp-=10;
                }
        }
        if(typ=='N')
        {
            for(int i=0; i<totm; i++)
                if(in(mon[i].x,mon[i].y))
                {
                    mon[i].need=1;
                    break;
                }
        }
        if(typ=='I')
        {
            for(int i=0; i<totm; i++)
                if(in(mon[i].x,mon[i].y))
                {
                    mon[i].ice=1;
                    break;
                }
        }
    }
}tow[60];
bool check(int x,int y)
{
    if(!(x>=0&&x<n&&y>=0&&y<m))return 0;
    if(mm[x][y]!='.'&&mm[x][y]!='T'&&mm[x][y]!='S')return 0;
    return 1;
}
void  route()
{
    memset(to,-1,sizeof(to));
    memset(dis,-1,sizeof(dis));
    queue<int>q[2];
    to[tx][ty][0]=tx;
    to[tx][ty][1]=ty;
    dis[tx][ty]=0;
    q[0].push(tx);
    q[1].push(ty);
    while(!q[0].empty())
    {
        int x=q[0].front();
        q[0].pop();
        int y=q[1].front();
        q[1].pop();
        for(int i=0; i<4; i++)
        {
            int nx=x+dx[i];
            int ny=y+dy[i];
            if(!check(nx,ny))continue;
            if(to[nx][ny][0]!=-1)continue;
            to[nx][ny][0]=x;
            to[nx][ny][1]=y;
            dis[nx][ny]=dis[x][y]+1;
            q[0].push(nx);
            q[1].push(ny);
        }
    }
}
void born(int a)
{
    mon[totm++].born(a);
}
void clcmon()
{
    sort(mon,mon+totm);
    for(int i=0; i<totm; i++)
    {
        if(mon[i].hp<=0)
        {
            totm=i;
            break;
        }
    }
}
bool checklose()
{
    for(int i=0; i<totm; i++)
    {
        if(mon[i].x==tx&&mon[i].y==ty)
            return 1;
    }
    return 0;
}
bool move(int now)
{
    for(int i=0; i<totm;i++)mon[i].move();
    if(now<=tot)born(now);
    clcmon();
    return checklose();
}
void attack()
{
    for(int i=0; i<tott; i++)
    {
        tow[i].attack();
    }
}
bool judge(monster m1,monster m2)
{
    if(m1.x!=m2.x)return 0;
    if(m1.y!=m2.y)return 0;
    if(m1.ice!=m2.ice)return 0;
    if(m1.need!=m2.need)return 0;
    if(m1.hp!=m2.hp)return 0;
    return 1;
}
bool same()
{
    if(totmm!=totm)return 0;
    for(int i=0; i<totm;i++)if(!judge(tmm[i],mon[i])) return 0;
    return 1;
}
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        cin>>n>>m>>tot>>Hp;
        for(int i=0; i<n; i++)
            cin>>mm[i];
        totm=tott=0;
        for(int i=0; i<n; i++)
            for(int j=0; j<m; j++)
            {
                if(mm[i][j]=='S')
                {
                    sx=i;
                    sy=j;
                }
                else if(mm[i][j]=='T')
                {
                    tx=i;
                    ty=j;
                }
                else if(mm[i][j]=='B')
                {
                    tow[tott++]=tower(i,j,'B');
                }
                else if(mm[i][j]=='F')
                {
                    tow[tott++]=tower(i,j,'F');
                }
                else if(mm[i][j]=='N')
                {
                    tow[tott++]=tower(i,j,'N');
                }
                else if(mm[i][j]=='I')
                {
                    tow[tott++]=tower(i,j,'I');
                }
            }
            route();
            int ans=0;
            while(1)
            {
                ans++;
                if(move(ans))
                {
                    ans=-1;
                    break;
                }
                attack();
                clcmon();
                if(ans>=tot&&totm==0)break;
                if(ans>tot&&same())
                {
                    ans=-1;
                    break;
                }
                for(int i=0;i<totm;i++)
                    tmm[i]=mon[i];
                totmm=totm;
            }
            cout<<ans<<endl;
    }
}

 

相关日志

  1. 2016.05.04

    FZU 2041 checker(搜索)

    题目链接:http://acm.fzu.ed…

  2. 2016.07.10

    Codeforces Round #361 (Div. 2)A. Mike and Cellphone

    果然CF是三亿coder的coding梦想(…

  3. 2016.05.11

    ZOJ 3702 Gibonacci number

    题目地址:http://acm.zju.ed…

  4. 2016.07.10

    Codeforces Round #361 (Div. 2)B. Mike and Shortcuts

    题意迷之简短。大意就是:一个城市i到另一个城…

  5. 2016.05.09

    FZU 2093 寻找兔子(状压dp)

    题目地址:http://acm.fzu.ed…

  6. 2016.07.13

    安利一波答案 经典算法设计

      (更多…)

评论

  1. trash 2016.05.12

    interesting!不愧我Y。

在此评论中不能使用 HTML 标签。