记忆化搜索之一: hihoCoder 1491 : Monster Killing

来源:互联网 发布:淘宝买被子好吗 编辑:程序博客网 时间:2024/06/08 12:37

微软2017年预科生计划在线编程笔试
第一场 第三题
hihoCoder #1491 : Monster Killing
http://hihocoder.com/problemset/problem/1491

可以用记忆化搜索做
参考 这篇http://blog.csdn.net/buptzhengchaojie/article/details/69831275 的思路。
下面是C++代码

#include<iostream>#include<cstdio>#include<cassert>#include<algorithm>#include<cstring>#include<queue>using namespace std;const int STATE=(1<<25);const int offset=8;int visited[STATE*offset];char maze[10][10];int n,m;int player_hp;int player_attack;struct Monster{    int hp;    int attack;    char type;    unsigned mask;    int i;    int j;    int cost[6];    int buff[6];    void set(int h,int a,char t)    {        hp=h;        attack=a;        type=t;    }    void cal()    {        for(int i=0;i<=5;i++)        {            int j=i;            calcost(player_attack,j,cost[i],buff[i]);        }    }    void calcost(int player_attack,int buff,int& cost ,int &buffleft)    {        int monster_hp=hp;        cost=0;        while(buff && monster_hp>0)        {            monster_hp-=player_attack;            buff--;        }        if(monster_hp>0)        {            int t=(monster_hp+player_attack-1)/player_attack;            cost+=attack*t;        }        if(type=='S')        {            buff=5;        }        buffleft=buff;    }};Monster monsters[100];unsigned allmask;inline unsigned getmask(int i,int j){    return 1<<(i*(m+1)+j);}inline unsigned neighbormask(unsigned mask){    unsigned r;    r=(mask<<(1+m))        | (mask>>(1+m))        | (mask>>1)        | (mask<<1);    return r;}inline unsigned getstate(int i,int j,int buff){    return ((1<<(i*(m+1)+j))<<3)+buff;}int search(int cur){    if(visited[cur]!=0)    {        return visited[cur];    }    int curmask=(cur>>3);    int curbuff=cur&7;    if((curmask&allmask)==allmask)    {        visited[cur]=1;        return 1;    }    visited[cur]=player_hp+1;    for(int i=0;i<n;i++)    {        for(int j=0;j<m;j++)        {            unsigned tempmask=getmask(i,j);            if(tempmask&curmask)// visited already            {                continue;            }            unsigned neighbor=neighbormask(tempmask);            if((neighbor&curmask)==0)// no neighbor            {                continue;            }            int tempbuff=curbuff-1;            if(tempbuff<0)            {                tempbuff=0;            }            int cost=0;            if(maze[i][j]=='.')//road            {                //buff already taken care of            }            else//monster            {                //assert(maze[i][j]=='M' || maze[i][j]=='S');                int monster_i=maze[i][j];                cost=monsters[monster_i].cost[tempbuff];                tempbuff=monsters[monster_i].buff[tempbuff];            }            if(tempbuff<=1)            {                tempbuff=0;            }            int cost2=search(((curmask|tempmask)<<3)|tempbuff);            int cost_total=cost2+cost;            visited[cur]=min(visited[cur],cost_total);        }    }    return visited[cur];}int main(){    int hp;    int attack;    int entrance_i;    int entrance_j;    //while(cin>>n>>m)    cin>>n>>m;    {        assert((m+1)*n<=25);        int s_c=0;        int m_c=0;        for(int i=0;i<n;i++)        {            cin>>maze[i];        }        int monster_len=0;        allmask=0;        for(int i=0;i<n;i++)        {            for(int j=0;j<m;j++)            {                if(maze[i][j]=='S')                {                    s_c++;                    scanf("%d%d",&hp,&attack);                    //cin>>hp>>attack;                    maze[i][j]=monster_len;                    monsters[monster_len++].set(hp,attack,'S');                    allmask |= getmask(i,j);                }                else if(maze[i][j]=='M')                {                    m_c++;                    scanf("%d%d",&hp,&attack);                    //cin>>hp>>attack;                    maze[i][j]=monster_len;                    monsters[monster_len++].set(hp,attack,'M');                    allmask |= getmask(i,j);                }                else if(maze[i][j]=='D')                {                    entrance_i=i;                    entrance_j=j;                }            }        }        scanf("%d%d",&player_hp,&player_attack);        //cin>>player_hp>>player_attack;        for(int i=0;i<monster_len;i++)        {            monsters[i].cal();        }        //memset(visited,-1,sizeof(visited));        int e=getstate(entrance_i,entrance_j,5);        int x=player_hp-search(e)+1;        if(x<=0)        {            cout<<"DEAD"<<endl;        }        else        {            cout<<x<<endl;        }    }    return 0;}
原创粉丝点击