hdu Waiting ten thousand years for Love

被这道题坑到了,如果单纯的模拟题目所给的步骤,就会出现同一个位置要走两次的情况。。。所以对于bfs来说会很头痛。

第一个代码是wa掉的代码,经过调试才知道这个wa的有点惨,因为前面的操作有可能会阻止后面的正确操作:

#include"iostream"
#include"stdio.h"
#include"algorithm"
#include"cmath"
#include"string.h"
#include"queue"
#define mx 100
using namespace std;
char castle[mx][mx];
int n,m,t,p,sx,sy,ex,ey;
struct node
{
    int x,y;
    int magic;
    int times;
    char flag;//用来标记当前位置是@还是.
    friend bool operator<(node a,node b)
    {
        if(b.times!=a.times) return b.times<a.times;
        return a.magic<b.magic;
    }
};
int dir[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
bool judge(int x,int y)
{
    if(x>=0&&x<n&&y>=0&&y<m&&castle[x][y]!='#') return true;
    return false;
}
void bfs()
{
    node cur,next;
    int i;
    cur.x=sx;cur.y=sy;cur.times=0;cur.magic=p;cur.flag='.';
    priority_queue<node>q;
    q.push(cur);
    while(!q.empty())
    {
        cur=q.top();
        q.pop();
       // cout<<cur.x<<' '<<cur.y<<' '<<cur.magic<<' '<<cur.times<<' '<<cur.flag<<endl;
        if(cur.x==ex&&cur.y==ey&&cur.times<=t)
        {
            cout<<"Yes, Yifenfei will kill Lemon at "<<cur.times<<" sec."<<endl;
            return;
        }
         if(cur.times>t)
        {
            cout<<"Poor Yifenfei, he has to wait another ten thousand years."<<endl;
            return;
        }
      
        for(i=0;i<4;i++)
        {
            next.x=cur.x+dir[i][0];
            next.y=cur.y+dir[i][1];
            if(judge(next.x,next.y))
            {
                if(cur.flag=='@'&&cur.magic>0)
                {
                    next.times=cur.times+1;
                    next.magic=cur.magic-1;
                    if(castle[next.x][next.y]=='@')next.flag='@';
                    else next.flag='.';
                    castle[next.x][next.y]='#';
                    q.push(next);
                }
                else if(cur.flag=='.')
                {
                    if(castle[next.x][next.y]=='@')
                    {
                        if(cur.magic>0)
                        {
                            next.times=cur.times+1;
                            next.magic=cur.magic-1;
                            next.flag='@';
                            castle[next.x][next.y]='#';
                            q.push(next);
                        }
                    }
                    else
                    {
                        next.times=cur.times+2;
                        next.magic=cur.magic;
                        next.flag='.';
                        castle[next.x][next.y]='#';
                        q.push(next);
                        if(cur.magic>0)
                        {
                            next.times=cur.times+1;
                            next.magic=cur.magic-1;
                            q.push(next);
                        }

                    }
                }
            }
        }
    }
    cout<<"Poor Yifenfei, he has to wait another ten thousand years."<<endl;
}
int main()
{
    int c=0;
    while(scanf("%d%d%d%d",&n,&m,&t,&p)==4)
    {
        int i,j;
        for(i=0;i<n;i++)
            for(j=0;j<m;j++)
        {
            cin>>castle[i][j];
            if(castle[i][j]=='Y') {sx=i;sy=j;castle[i][j]='#';}
            else if(castle[i][j]=='L'){ex=i;ey=j;castle[i][j]='.';}
        }
        cout<<"Case "<<++c<<":"<<endl;
        bfs();
    }
    return 0;
}
View Code

参考大神的解法后才知道这题在一开始就应该对步骤简化,因为只有前后两步都是’.'是才可以用走的,。其他任何情况下都要用飞的,所以没有必要像之前那样分

很多种情况讨论。果然编程之前还是要多思考思考尽量简化步骤,这样不仅可以提高效率,而且还可以避免发生不必要的错误。

#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
char g[100][100];
bool vis[88][88][88];
int n,m,p,t,si,sj,ans;
int dir[4][2]={{1,0},{0,1},{-1,0},{0,-1}};
struct node
{
    int step,p,x,y;
    node(int a=0,int b=0,int c=0,int d=0):x(a),y(b),p(c),step(d){}
    bool friend operator <(const node a,const node b)
    {
        return a.step>b.step;
    }
};
void BFS()
{
    priority_queue<node> Q;
    node f=node(si,sj,p,0);
    Q.push(f);
    memset(vis,false,sizeof(vis));
    vis[si][sj][p]=true;
    node temp;
    while(!Q.empty())
    {
        temp=Q.top();
        Q.pop();
        if(temp.step>t)
            return ;
        if(g[temp.x][temp.y]=='L')
        {
            ans=temp.step;
            return ;
        }
        for(int k=0;k<4;k++)
        {
            int i=dir[k][0]+temp.x;
            int j=dir[k][1]+temp.y;
            if(i<0||i>n-1 || j<0 || j>m-1||g[i][j]=='#')
                continue;
            if(temp.p!=0 && !vis[i][j][temp.p-1])
            {
                vis[i][j][temp.p-1]=true;
                Q.push(node(i,j,temp.p-1,temp.step+1));
            }
            if(g[temp.x][temp.y]!='@' && g[i][j]!='@'&&!vis[i][j][temp.p])
            {
                vis[i][j][temp.p]=true;
                Q.push(node(i,j,temp.p,temp.step+2));
            }
        }
    }
    return ;
}
int main()
{
    int cas=0;
    while(scanf("%d %d %d %d",&n,&m,&t,&p)==4)
    {
        for(int i=0;i<n;i++)
        {
            scanf("%s",g[i]);
            for(int j=0;j<m;j++)
                if(g[i][j]=='Y')
                    si=i,sj=j;
        }
        ans=100001;
        BFS();
        printf("Case %d:
",++cas);
        if(ans>t)
            printf("Poor Yifenfei, he has to wait another ten thousand years.
");
        else printf("Yes, Yifenfei will kill Lemon at %d sec.
",ans);
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/acm-jing/p/4333336.html