现在的位置: 首页 > 综合 > 正文

hdu4771 Stealing Harry Potter’s Precious 2013 Asia Hangzhou Regional Contest

2018年04月25日 ⁄ 综合 ⁄ 共 2222字 ⁄ 字号 评论关闭

去年写这一题不知道BFS要避免重复访问相同的状态,一直MLE。。拖了一年开始写了。

很明显的状态压缩,used[x][y][key]用来标记表示在[x,y]点处拿到key的宝物的状态,key用二进制数表示是否取得了某一个宝物,例如1001表示取得了第一个和第四个宝物。

然后这次因为访问的状态表急错了也MLE了几次。。==

#include<iostream>
#include<stdio.h>
#include<cstdio>
#include<stdlib.h>
#include<vector>
#include<string>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<stack>
#include<queue>
#include <ctype.h>
using namespace std;

int N;
int M;
int K;
int mp[110][110];
int used[110][110][1<<4];
//int d[110][110][1<<4];
int ans;
int dx[]={0,-1,0,1};
int dy[]={-1,0,1,0};
struct node
{
public:
    int x;
    int y;
    int key;
    int step;
    node(){}
    node(int xx,int yy,int k,int s)
    {
        x=xx;
        y=yy;
        key=k;
        step=s;
    }
};
pair<int,int> st;
pair<int,int> prec[4];
queue<node>q;
void bfs()
{
    while(!q.empty()) q.pop();
    int s=0;
    if(mp[st.first][st.second]>=2)
    {
        s=(1<<mp[st.first][st.second])-2;
    }
    node a=node(st.first,st.second,s,0);
    q.push(a);
    while(!q.empty())
    {
        node tmp=q.front();
        q.pop();
        int x=tmp.x;
        int y=tmp.y;
        int key=tmp.key;
        int step=tmp.step;
        used[x][y][key]=false;
   //    cout<<x<<" "<<y<<" "<<key<<" "<<step<<endl;

        if(key==((1<<K)-1))
        {
            ans=step;//need to get min?
            return;
        }
        for(int i=0;i<4;i++)
        {
            if(x+dx[i]>=1&&x+dx[i]<=N&&y+dy[i]>=1&&y+dy[i]<=M&&mp[x+dx[i]][y+dy[i]]>=1)//used[x+dx[i]][y+dy[i]]&& 该点是否走过要根据下面key的状态判断,我都不造这里USED只写了两维怎么还能进if的
            {
                if(mp[x+dx[i]][y+dy[i]]>=2&&mp[x+dx[i]][y+dy[i]]<=(K+1))
                {
                    int new_k=mp[x+dx[i]][y+dy[i]]-2;//这里米有考虑两个宝物在同一个格子里的case
                   // if((key&(1<<new_k))==0)//used在下面才判定,所以这里不能有if
                //    {
                        if(used[x+dx[i]][y+dy[i]][key|(1<<new_k)]==false) continue;
                        node tmp2=node(x+dx[i],y+dy[i],key|(1<<new_k),step+1);
                        q.push(tmp2);
                        used[x+dx[i]][y+dy[i]][key|(1<<new_k)]=false;//一定要标记访问,否则会MLE
                 //   }

                }
                else
                {
                    if(used[x+dx[i]][y+dy[i]][key]==false) continue;
                    node tmp2=node(x+dx[i],y+dy[i],key,step+1);
                    q.push(tmp2);
                    used[x+dx[i]][y+dy[i]][key]=false;
                }
            }
        }

    }


}
int main()
{
    freopen("input.txt","r",stdin);
    // freopen("data.txt","r",stdin);
     //freopen("out1.txt","w",stdout);
     while(true)
     {
         scanf("%d %d",&N,&M);
         memset(used,true,sizeof(used));
         memset(mp,true,sizeof(mp));
         ans=-1;
         if(N==0&&M==0) break;
         else
         {
             for(int i=1;i<=N;i++)
             {
                 for(int j=1;j<=M;j++)
                 {
                     char str;
                     cin>>str;
                     if(str=='#') mp[i][j]=0;
                     else if(str=='.') mp[i][j]=1;
                     else if(str=='@')
                     {
                         mp[i][j]=0;
                         st.first=i;
                         st.second=j;
                     }
                 }
             }
         }
         scanf("%d",&K);
         for(int i=0;i<K;i++)
         {
             int x,y=0;
             scanf("%d %d",&x,&y);
             mp[x][y]=i+2;
             prec[i]=make_pair(x,y);
         }
         bfs();
         printf("%d\n",ans);
        // puts(" ");
     }
    return 0;
}



抱歉!评论已关闭.