2182: 【USACO】What‘s Up With Gravity?

25 篇文章 0 订阅
15 篇文章 0 订阅

2182: 【USACO】What's Up With Gravity?

时间限制: 1.000 Sec  内存限制: 32 MB
提交: 25  解决: 20
[命题人:][下载数据: 90]

提交状态报告

题目描述

Captain Bovidian is on an adventure to rescue her crew member, Doctor Beefalo. Like all great adventures, this story plays out in a two dimensional N by M grid (1 <= N, M <= 500), representing a side view of the captain's world. Some grid cells are empty while others are blocked and cannot be traversed.
Unfortunately, Captain Bovidian cannot jump. She must obey the following rules of physics while traversing her world.
1) If there is no cell directly underneath Captain Bovidian (that is, if she is at the edge of the grid), then she flies out into space and fails her mission.
2) If the cell directly underneath Captain Bovidian is empty, then she falls into that cell.
3) Otherwise:
a) Captain Bovidian may move left or right if the corresponding cell exists and is empty.
b) Or, Captain Bovidian may flip the direction of gravity.
When Captain Bovidian changes the direction of gravity, the cell that's 'underneath' her (as mentioned in rules 1 and 2) toggles between the cell with one higher row index and the cell with one lower row index (the first row in the input has index 1, and the last row has index N). Initially, the cells with one higher row index are underneath Captain Bovidian.
Doctor Beefalo is lost somewhere in this world. Help Captain Bovidian arrive at her cell using the least number of gravity flips as possible. If it is impossible to reach Doctor Beefalo, please output -1.

输入

* Line 1: Two space-separated integers N and M.
* Lines 2..1+N: Line i+1 describes the ith row of Captain Bovidian's world: '.' indicates an empty cell, '#' indicates a blocked cell, 'C' indicates Captain Bovidian's starting position, and 'D' indicates Doctor Beefalo's starting position.

输出

* Line 1: A single integer indicating the minimum number of times Captain Bovidian must flip gravity to reach Doctor Beefalo, or -1 if it is impossible to reach Doctor Beefalo.

样例

输入  复制

5 5 ##### #...# #...D #C... ##.##

输出  复制

3

提示

OUTPUT DETAILS:
The captain starts at position (4, 2). She flips gravity and falls to position (2, 2) and then moves right twice to arrive at (2, 4). She flips gravity again and falls to position (4, 4) and then moves right once to position (4, 5). Finally she flips gravity again to fall to Doctor Beefalo's position at (3, 5).

来源/分类

USACO 2013 Open Silver 

AC

#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
using namespace std;
const int N = 505;
const int INF = 0x3f3f3f3f;

int n,m,g[N][N],sx,sy,tx,ty; char s[N];
int d[N][N][2]; bool vis[N][N][2];

struct State{
    int x,y,op;
    State(){}
    State(int _x,int _y,int _op){ x=_x; y=_y; op=_op; }
};

queue<State> q;

void upd(State u,State v){
    if(d[v.x][v.y][v.op] > d[u.x][u.y][u.op]){
        d[v.x][v.y][v.op] = d[u.x][u.y][u.op] + (u.op==v.op?0:1);
        if(!vis[v.x][v.y][v.op]){
            vis[v.x][v.y][v.op]=true; q.push(v);
        }
    }
}

int spfa(){
    memset(d,0x3f,sizeof(d));
    memset(vis,false,sizeof(vis));
    q.push(State(sx,sy,1)); vis[sx][sy][1]=true; d[sx][sy][1]=0;
    while(!q.empty()){
        State u=q.front(); q.pop(); vis[u.x][u.y][u.op]=false;
        int dx=(u.op==1?1:-1);
        if(u.x+dx>=1 && u.x+dx<=n){
            if(g[u.x+dx][u.y]==0){
                upd(u,State(u.x+dx,u.y,u.op));
            }
            else{
                if(u.y+1<=m && g[u.x][u.y+1]==0){
                    upd(u,State(u.x,u.y+1,u.op));
                }
                if(u.y-1>=1 && g[u.x][u.y-1]==0){
                    upd(u,State(u.x,u.y-1,u.op));
                }
                upd(u,State(u.x,u.y,u.op^1));
            }
        }
    }
    return min(d[tx][ty][1],d[tx][ty][0]);
}

int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        scanf("%s",s+1);
        for(int j=1;j<=m;j++){
            if(s[j]=='#') g[i][j]=1;
            else g[i][j]=0;
            if(s[j]=='C') sx=i, sy=j;
            if(s[j]=='D') tx=i, ty=j;
        }
    }
    int ans=spfa();
    if(ans==INF) puts("-1");
    else printf("%d\n",ans);
}

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值