ZOJ-3865 Superbot

题目:

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5477

题意:

机器人在地图中找钻石的游戏,给出一个地图,' * ' 表示墙,@表示起点,$表示钻石,移动方向取决于当前光标在哪个移动按钮上。

每秒可以左右移动一下光标位置或者按当前光标移动一下机器人或者什么都不做。

同时按钮在旋转,每len秒4个按钮向右旋转一格。

求到达钻石位置所需最小时间。

思路:

只有10*10的地图,直接枚举所有方式搜索。

用BFS,在结构体中保存每种操作的所有信息:位置,当前时间,光标位置,停留时间。

之后对于队列中取出的每种情况都可以分成最多4中情况:

按当前光标位置移动机器人,向左移动光标,向右移动光标,什么都不做(等旋转)。

注意在不移动的情况下要更新停留时间,防止死循环,每个位置最多停留2秒。

在判断移动机器人时,加入当前时间计算按钮旋转次数,确定当前移动方向是否可移动。

代码:

#define N 112

int n,m;
int x,y,xx,yy;
int flag,sum,ave,ans,res,len;
int g[N][N];
int dir[4][2]={0,-1,0,1,-1,0,1,0};
bool vis[N][N];
char s[101];

struct node
{
    int x,y;
    int r,w;
    int num;
}tn;

void init()
{
    memset(vis,false,sizeof(vis));
    memset(g,0,sizeof(g));
}
void solve()
{
    int i,j,k,tx,ty;
    sum=1;
    queue<node> q;
    while(!q.empty())q.pop();
    node h,p;
    h.x=x;h.y=y;
    h.r=0;h.w=0;
    h.num=0;
    q.push(h);
    while(!q.empty())
    {
        h=q.front();q.pop();
        vis[h.x][h.y]=true;
        //计算移动位置
        x=h.x+dir[(1000*4-h.w/len+h.r)%4][0];
        y=h.y+dir[(1000*4-h.w/len+h.r)%4][1];
        if(x==xx&&y==yy)
        {
            printf("%d\n",h.w+1);
            return;
        }
        //移动机器人
        if(g[x][y]&&!vis[x][y])
        {
            p.x=x;p.y=y;
            p.r=h.r;
            p.w=h.w+1;
            p.num=0;
            q.push(p);
            vis[x][y]=true;
        }
        if(h.num<2)
        {
            p.x=h.x;p.y=h.y;
            p.w=h.w+1;
            p.num=h.num+1;
            //右移光标
            p.r=h.r+1;
            p.r%=4;
            q.push(p);
            //左移光标
            p.r=h.r+4-1;
            p.r%=4;
            q.push(p);
            //什么都不做
            p.r=h.r;
            q.push(p);
        }
    }
    printf("YouBadbad\n");
}
int main()
{
    int i,j,k,kk,t,z;
    scanf("%d",&k);
    while(k--)
    {
        init();
        scanf("%d%d%d",&n,&m,&len);
        for(i=1;i<=n;i++)
        {
            scanf("%s",s);
            for(j=1;j<=m;j++)
            {
                if(s[j-1]=='.')
                    g[i][j]=1;
                else if(s[j-1]=='*')
                    g[i][j]=0;
                else if(s[j-1]=='@')
                    g[i][j]=0,x=i,y=j;
                else
                    g[i][j]=1,xx=i,yy=j;
            }
        }
        solve();
    }
    return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值