Andrew Stankevich Contest 4——Driving Straight

题目连接

  • 题意:
    输入m、n,之后是2*m-1行,2*n-1列。‘ ’表示不能通过,‘+’可以通过,‘-’、‘|’只允许一个方向通过(和符号相同的方向),求从左下角到右上角的最短路并输出:输出时候,尽量保持之前的运动方向。每到一个‘+’点,输出当前采取的运动操作:R,右转;L,左转;F,直行。最开始的时候输出:N,向北走;E向东走
  • 分析:
    简单的最短路,就是输出路径的时候麻烦一点。右上角开始bfs求最短路,左下角开始找路径即可
const int INF = 0x3f3f3f3f;
const double EPS = 1e-9;
const int MOD = 1000000007;
const double PI = acos(-1.0);
const int MAXN = 900;

char ipt[MAXN][MAXN];
int dp[MAXN][MAXN];
int n, m;

int dx[] = {-1, 0, 1, 0};
int dy[] = {0, 1, 0, -1};
char judge[] = {'|', '-', '|', '-'};
struct Node
{
    int x, y;
    Node(int x = 0, int y = 0) : x(x), y(y) {}
} t;
bool check(int r, int c, int dir)
{
    return ipt[r][c] == '+' || ipt[r][c] == judge[dir];
}
void bfs(int sx, int sy)
{
    queue<Node> q;
    q.push(Node(sx, sy));
    dp[sx][sy] = 0;
    while (!q.empty())
    {
        t = q.front(); q.pop();
        REP(i, 4)
        {
            if (check(t.x, t.y, i))
            {
                int tx = t.x + dx[i];
                int ty = t.y + dy[i];
                if (dp[tx][ty] == INF && ipt[tx][ty] != ' ' && ipt[tx][ty] != 0 && check(tx, ty, i))
                {
                    dp[tx][ty] = dp[t.x][t.y] + 1;
                    q.push(Node(tx, ty));
                }
            }
        }
    }
}

void display(int x, int y, int dir)
{
    if (x == 1 && y == m)
    {
        return;
    }
    int ldir = (dir + 3) % 4, rdir = (dir + 1) % 4;
    int tx, ty;
    tx = x + dx[dir]; ty = y + dy[dir];
    if (ipt[tx][ty] != 0 && dp[tx][ty] == dp[x][y] - 1)
    {
        if (ipt[x][y] == '+')
            putchar('F');
        display(tx, ty, dir);
        return;
    }

    tx = x + dx[ldir]; ty = y + dy[ldir];
    if (ipt[tx][ty] != 0 && dp[tx][ty] == dp[x][y] - 1)
    {
        if (ipt[x][y] == '+')
            putchar('L');
        display(tx, ty, ldir);
        return;
    }

    tx = x + dx[rdir]; ty = y + dy[rdir];
    if (ipt[tx][ty] != 0 && dp[tx][ty] == dp[x][y] - 1)
    {
        if (ipt[x][y] == '+')
            putchar('R');
        display(tx, ty, rdir);
        return;
    }
}

int main()
{
    freopen("straight.in", "r", stdin);
    freopen("straight.out", "w", stdout);
    while (~RII(n, m))
    {
        n = n * 2 - 1; m = m * 2 - 1;
        getchar();
        CLR(dp, INF);
        CLR(ipt, 0);
        FE(i, 1, n)
            gets(ipt[i] + 1);
        bfs(1, m);
        REP(i, 2)
        {
            int tx = n + dx[i];
            int ty = 1 + dy[i];
            if (ipt[tx][ty] != 0 && check(n, 1, i) && check(tx, ty, i) && dp[tx][ty] == dp[n][1] - 1)
            {
                puts(i ? "E" : "N");
                display(tx, ty, i);
                break;
            }
        }
        puts("");
    }
    return 0;
}

给点测试数据:
2 2
+--
|||
+++

2 2
+--
|
+

2 2
+--
+-+
--+

2 2
+++
+++
+++

2 2
+++
-++
+++

4 4
+-+ +-+
| |   |
+ +-+-+
|   -
+-+-+-+
|     |
+-+-+-+



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值