HDU 1732 Push Box(搜索)

本文介绍了一种解决特定推箱子问题的暴力搜索算法实现,该算法针对有且仅有三个箱子的游戏状态进行求解,利用C++编程语言,通过记录箱子的位置变化来寻找达到目标状态所需的最少步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意:推箱子,有且只有3个箱子

思路:暴搜:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>

using namespace std;
char map[9][9];
bool v[8][8][8][8][8][8][8][8];
int n,m;
int dx[]={0,0,-1,1};
int dy[]={-1,1,0,0};
struct cpoint{
    int x,y;
};
struct node{
    cpoint a[4];
    int dis;
}st,en;
queue<node> que;
bool aim[9][8];
bool ok(node &e)
{
    for(int i=0;i<3;i++)
    {
        if(!aim[e.a[i].x][e.a[i].y]) return false;
    }
    return true;
}
bool oor(int &x,int &y)
{
    if(x<0||x>=n) return false;
    if(y<0||y>=m) return false;
    return true;
}
int solve()
{
    memset(aim,false,sizeof(aim));
    memset(v,false,sizeof(v));
    for(int i=0;i<3;i++)
    aim[en.a[i].x][en.a[i].y] = true;
    st.dis=0;
    while(!que.empty()) que.pop();
    que.push(st);
    node e,t;
    while(!que.empty())
    {
        e = que.front();que.pop();
        if(ok(e)) return e.dis;
        if(v[e.a[0].x][e.a[0].y][e.a[1].x][e.a[1].y][e.a[2].x][e.a[2].y][e.a[3].x][e.a[3].y])
        continue;
        v[e.a[0].x][e.a[0].y][e.a[1].x][e.a[1].y][e.a[2].x][e.a[2].y][e.a[3].x][e.a[3].y]=true;
        for(int i=0;i<4;i++)
        {
            int tx=e.a[3].x+dx[i],ty=e.a[3].y+dy[i];
            if(!oor(tx,ty)||map[tx][ty]=='#') continue;
            int j=0;
            for(;j<3;j++)
            if(e.a[j].x==tx&&e.a[j].y==ty) break;
            if(j>=3)
            {
                t=e,t.a[3].x=tx,t.a[3].y=ty;
                t.dis++;
                que.push(t);
            }
            else
            {
                tx+=dx[i];ty+=dy[i];
                if(!oor(tx,ty)||map[tx][ty]=='#') continue;
                int k=0;
                for(;k<3;k++)
                if(e.a[k].x==tx&&e.a[k].y==ty) break;
                if(k>=3)
                {
                    t=e,t.a[j].x=e.a[j].x+dx[i],
                    t.a[j].y=e.a[j].y+dy[i];
                    t.a[3].x=e.a[j].x,t.a[3].y=e.a[j].y;
                    t.dis++;
                    que.push(t);
                }
            }
        }
    }return -1;
}
int main()
{
    //freopen("in.txt","r",stdin);
    while(~scanf("%d%d",&n,&m))
    {
        int cnt1=0,cnt2=0;
        for(int i=0;i<n;i++)
        {
            scanf("%s",map[i]);
            for(int j=0;j<m;j++)
            {
                if(map[i][j]=='X')
                st.a[3].x=i,st.a[3].y=j;
                else if(map[i][j]=='*')
                st.a[cnt1].x=i,st.a[cnt1++].y=j;
                else if(map[i][j]=='@')
                en.a[cnt2].x=i,en.a[cnt2++].y=j;
                if(map[i][j]!='#') map[i][j]='.';
            }
        }
        printf("%d\n",solve());

    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值