【POJ1101&OpenJudge2802】The Game 小游戏(BFS+记忆化)

传送门

  • 题目:
    在这里插入图片描述
    在这里插入图片描述
  • 解题思路:
    注意题里的卡片位置(x,y)对应的是(列,行),可以将坐标转换成我们熟悉的(行,列)形式。图按常规方法存,只需要将要查询的(x,y)换成(y,x)即可。
    dis[x][y]表示从(x1,y1)到(x,y)所需要的最短线段数,在bfs的时候更新这个值。由于dis[x2][y2]可以由多个位置和多个方向更新来,队列中应该记录{x,y,dir,step},并且允许元素多次入队,但每个(x,y)只处理一次。
    网上的博客好多都是错的,假代码没过自己的样例,但AC了。。数据挺假的,题也挺假的。😤😤😤
  • ac代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <cmath>
#define maxn 80
using namespace std;
int dx[4] = {0, 0, -1, 1};//上,下,左,右
int dy[4] = {-1, 1, 0, 0};
int h, w;
char mp[maxn][maxn];
bool vis[maxn][maxn];
int dis[maxn][maxn];
struct node {
    int x, y, dir, step;
};
queue<node> q;
bool check(int x, int y)
{
    if(0<=x&&x<=h+1 && 0<=y&&y<=w+1 && !vis[x][y] && mp[x][y]==' ') return true;
    return false;
}
bool bfs(int x1, int y1, int x2, int y2)
{
    memset(vis, false, sizeof(vis));
    fill(dis[0], dis[0]+maxn*maxn, 9999999);
    while(!q.empty()) q.pop();
    bool flag = false;
    q.push({x1, y1, -1, 0});
    while(!q.empty())
    {
        node no = q.front(); q.pop();
        int x = no.x, y = no.y, dir = no.dir, step = no.step;
        if(x==x2 && y==y2) { flag = true; continue; }
        if(vis[x][y]) continue;
        vis[x][y] = true;
        for(int i = 0; i <= 3; i++)
        {
            int nx = x + dx[i];
            int ny = y + dy[i];
            if(check(nx, ny))
            {
                int nstep = step;
                if(i!=dir) nstep++;
                q.push({nx, ny, i, nstep});
                dis[nx][ny] = min(dis[nx][ny], nstep);
            }
        }
    }
    return flag;
}

int main()
{
    //freopen("/Users/zhangkanqi/Desktop/11.txt","r",stdin);
    int cnt1 = 0, cnt2 = 0;
    int x1, y1, x2, y2;
    while(scanf("%d %d", &w, &h)==2 && w&&h)
    {
        memset(mp, ' ', sizeof mp);
        getchar();
        for(int i = 1; i <= h; i++)
        {
            for(int j = 1; j <= w; j++) mp[i][j] = getchar();
            getchar();
        }
        printf("Board #%d:\n", ++cnt1);
        cnt2 = 0;
        while(scanf("%d %d %d %d", &x1, &y1, &x2, &y2)==4 && x1&&y1&&x2&&y2)
        {
            swap(x1, y1); swap(x2, y2);
            mp[x2][y2]=' ';
            if(bfs(x1, y1, x2, y2)) printf("Pair %d: %d segments.\n", ++cnt2, dis[x2][y2]);
            else printf("Pair %d: impossible.\n", ++cnt2);
            mp[x2][y2]='X';
        }
        printf("\n");
    }
    return 0;
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值