UVA589 Pushing Boxes

本文介绍了一种使用图论解决UVA589推箱子游戏问题的方法,通过设计状态四元组和路程二元组,利用SPFA算法找到最少推箱子次数和行走步数的解决方案。

UVA589 Pushing Boxes

题目地址

题意 : 推箱子游戏
  • 这里提供一种图论解法 。

  • 设计状态为四元组 ( P x , P y , B x , B y ) (Px,Py,Bx,By) (Px,Py,Bx,By) 分别代表人的坐标和箱子的坐标 。

  • 设计路程为二元组 D i s ( P u s h , W a l k ) Dis(Push,Walk) Dis(Push,Walk) 分别代表推箱子的次数和走路的次数。

  • 路程 A A A大于路程 B B B ,当 A . P u s h > B . P u s h 或 ( A . P u s h = = B . P u s h 且 A . W a l k > B . W a l k ) A.Push >B.Push或(A.Push==B.Push且A.Walk>B.Walk) A.Push>B.Push(A.Push==B.PushA.Walk>B.Walk)

    bool Cmp (const Dis &A , const Dis &B) {
        if (A.Push != B.Push ) return A.Push > B.Push ;
        else return A.Walk > B.Walk;
    }

  • 两个路程叠加,需要把两个属性分别叠加:

    Dis Plus (Dis &A , Dis &B) {
        Dis C ;
        C.Push = A.Push + B.Push ;
        C.Walk = A.Walk + B.Walk ;
        return C ;
    }
  • 然后用死了的 S P F A SPFA SPFA 就可以解决图论问题了

CODE
#include <stdio.h>
#include <string.h>
#define re register
#define Clean(X,K) memset(X,K,sizeof(X))
#define Jud(X,Y) (X<1||X>N||Y<1||Y>M||A[X][Y])
#define GC getchar()
int Qread () {
    int X = 0 ;
    char C = GC ;
    while (C > '9' || C < '0') C = GC ;
    while (C >='0' && C <='9') {
        X = X * 10 + C - '0' ;
        C = GC ;
    }
    return X ;
}
const int Maxn = 25 , Maxq = Maxn * Maxn , INF = 20021020 * 5 , Dx[]= {-1,1,0,0} , Dy[]= {0,0,-1,1};
const char C[]= {'N','S','W','E'} , c[]= {'n','s','w','e'} ;
char  Ans[Maxn * Maxn] = "";
int   Vis[Maxn][Maxn][Maxn][Maxn] ,N , M ,A[Maxn][Maxn] , Ex , Ey , Px[Maxn * Maxn * Maxn * Maxn] , Py[Maxn * Maxn * Maxn * Maxn] , Bx[Maxn * Maxn * Maxn * Maxn] , By[Maxn * Maxn * Maxn * Maxn];
char Nxt[Maxn][Maxn][Maxn][Maxn];
struct Node {
    int X1 ,Y1 , X2 , Y2 ;
};
Node FT[Maxn][Maxn][Maxn][Maxn] , E;
Node Findf(Node X) {
    if (FT[X.X1][X.Y1][X.X2][X.Y2].X2!=0)FT[X.X1][X.Y1][X.X2][X.Y2] = Findf(FT[X.X1][X.Y1][X.X2][X.Y2]) ;
    int Ln = strlen (Ans) ;
    Ans[Ln] = Nxt[X.X1][X.Y1][X.X2][X.Y2];
    Ans[Ln + 1] = '\0' ;
    return FT[X.X1][X.Y1][X.X2][X.Y2] ;
}
struct Dis {
    int Push , Walk ;
};
Dis Plus (Dis &A , Dis &B) {
    Dis C ;
    C.Push = A.Push + B.Push ;
    C.Walk = A.Walk + B.Walk ;
    return C ;
}
bool Cmp (const Dis &A , const Dis &B) {
    if (A.Push != B.Push ) return A.Push > B.Push ;
    else return A.Walk > B.Walk;
}
/*
头文件和准备工作
1. SPFA用到的队列分别是 Px[Maxn * Maxn * Maxn * Maxn] , Py[Maxn * Maxn * Maxn * Maxn] , Bx[Maxn * Maxn * Maxn * Maxn] , By[Maxn * Maxn * Maxn * Maxn];
各自代表了人的坐标,箱子的坐标。
2.定义距离为二元组(推动的次数,走的步数)
3.定义比较和叠加函数Plus和Cmp ;
4.Nxt数组记录了每一步所走的方向,用于递归输出路径。 
*/ 
Dis Mdis[Maxn][Maxn][Maxn][Maxn] ;
Dis One , Zero , _INF ;
Dis SPFA() {
    int H = 0 , T = 1 ;
    Dis Ans = _INF ;
    Clean( Vis , 0) , Clean(Mdis , 0x3f ) ;
    Clean(FT, 0) ;
    Mdis[Px[1]][Py[1]][Bx[1]][By[1]] = Zero ;
    Vis[Px[1]][Py[1]][Bx[1]][By[1]] = 1 ;
    while (H < T) {
        ++ H ;
        Vis[Px[H]][Py[H]][Bx[H]][By[H]] = 0 ;
        Node XX;
        XX.X1 = Px[H] , XX.Y1 = Py[H] , XX.X2 = Bx[H] , XX.Y2 = By[H] ;
        if (Bx[H] == Ex && By[H] == Ey) {
            if (Cmp (Ans , Mdis[Px[H]][Py[H]][Bx[H]][By[H]] ) ) {
                Ans = Mdis[Px[H]][Py[H]][Bx[H]][By[H]] ;
                E.X1 = Px[H] , E.Y1 = Py[H] , E.X2 = Bx[H] , E.Y2 = By[H] ;
            }
        }

        for (re int i = 0 ; i < 4 ; ++ i) {
            int Kx = Dx[i] + Px[H] , Ky = Dy[i] + Py[H];
            if (Jud (Kx , Ky)) continue ;
            if (Kx == Bx[H] && Ky == By[H]) {
                int Tx = Dx[i] + Bx[H] , Ty = Dy[i] + By[H] ;
                if (Jud (Tx , Ty)) continue ;
                if (Cmp (Mdis[Kx][Ky][Tx][Ty] , Plus (Mdis[Px[H]][Py[H]][Bx[H]][By[H]] , One))) {
                    Mdis[Kx][Ky][Tx][Ty] = Plus (Mdis[Px[H]][Py[H]][Bx[H]][By[H]] , One) ;
                    FT[Kx][Ky][Tx][Ty] = XX ;
                    Nxt[Kx][Ky][Tx][Ty] = C[i] ;
                    if (Vis[Kx][Ky][Tx][Ty]) continue ;
                    ++ T ;
                    Vis[Kx][Ky][Tx][Ty] = 1 ;
                    Px[T] = Kx , Py[T] = Ky , Bx[T] = Tx , By[T] = Ty;
                }
                continue ;
            }
            if (Cmp (Mdis[Kx][Ky][Bx[H]][By[H]]  ,Mdis[Px[H]][Py[H]][Bx[H]][By[H]] )) {
                Mdis[Kx][Ky][Bx[H]][By[H]] = Mdis[Px[H]][Py[H]][Bx[H]][By[H]] ;
                FT[Kx][Ky][Bx[H]][By[H]] = XX ;
                Nxt[Kx][Ky][Bx[H]][By[H]] = c[i] ;
                if (Vis[Kx][Ky][Bx[H]][By[H]]) continue ;
                ++ T ;
                Vis[Kx][Ky][Bx[H]][By[H]] = 1 ;
                Px[T] = Kx , Py[T] = Ky , Bx[T] = Bx[H] , By[T] = By[H] ;
            }
        }
    }
    return Ans;
}
/*
SPFA求最短路
实际上还是SPFA的模板,修改了路线长短的判断。 
*/
int main () {
    One.Push = 1 ;
    One.Walk = 0 ;
    Zero.Push = Zero.Walk = 0;
    _INF.Push = _INF.Walk = INF;
    
/*
这里定义了One和Zero,分别是0步和推1步,可以直接用在SPFA里面。 
*/
    //freopen ("UVA589.in" , "r" , stdin) ;
    N = Qread () , M = Qread() ;
    int T = 0 ;
    while (N + M) {
        ++T ;
        Clean(Ans,  0) ;
        Ans[0] = '\0' ;
        Clean(A , 0)  ;
        Clean(Nxt , 0) ;
        for (re int i = 1 ; i <= N; ++ i)
            for (re int j = 1 ; j <= M; ++ j) {
                char C = GC ;
                while (C != '.' && C != '#' && C !='S' && C != 'T' && C != 'B') C = GC ;
                A[i][j] = (C == '#' ? 1 : 0) ;
                if (C == 'S') Px[1] = i , Py[1] = j ;
                if (C == 'B') Bx[1] = i , By[1] = j ;
                if (C == 'T') Ex= i , Ey = j ;
            }
//读入数据
        Dis MinL = SPFA() ;//SPFA 计算最短路 
        Findf(E) ;//递归查找路径 
        printf ("Maze #%d\n" , T) ;
        if (MinL.Push  == INF) printf ("Impossible.\n");
        else
        printf ("%s\n" , Ans) ;
        putchar(10) ;
        N = Qread() , M = Qread() ;
    }
    fclose (stdin) ;
    fclose (stdout);
    return 0;
}

Thanks!

六自由度机械臂ANN人工神经网络设计:正向逆向运动学求解、正向动力学控制、拉格朗日-欧拉法推导逆向动力学方程(Matlab代码实现)内容概要:本文档围绕六自由度机械臂的ANN人工神经网络设计展开,详细介绍了正向与逆向运动学求解、正向动力学控制以及基于拉格朗日-欧拉法推导逆向动力学方程的理论与Matlab代码实现过程。文档还涵盖了PINN物理信息神经网络在微分方程求解、主动噪声控制、天线分析、电动汽车调度、储能优化等多个工程与科研领域的应用案例,并提供了丰富的Matlab/Simulink仿真资源和技术支持方向,体现了其在多学科交叉仿真与优化中的综合性价值。; 适合人群:具备一定Matlab编程基础,从事机器人控制、自动化、智能制造、电力系统或相关工程领域研究的科研人员、研究生及工程师。; 使用场景及目标:①掌握六自由度机械臂的运动学与动力学建模方法;②学习人工神经网络在复杂非线性系统控制中的应用;③借助Matlab实现动力学方程推导与仿真验证;④拓展至路径规划、优化调度、信号处理等相关课题的研究与复现。; 阅读建议:建议按目录顺序系统学习,重点关注机械臂建模与神经网络控制部分的代码实现,结合提供的网盘资源进行实践操作,并参考文中列举的优化算法与仿真方法拓展自身研究思路。
### 解决 Git Push 一直处于卡住状态的方法 当遇到 `git push` 卡住的情况时,可能的原因有多种。以下是常见的原因及其解决方案: #### 1. 网络连接问题 网络不稳定可能导致推送过程被中断或延迟。可以尝试以下方法来验证并解决问题: - 使用 `-v` 参数查看详细的日志信息以便定位具体问题[^1]。 ```bash git push -v ``` 如果发现请求超时或者无法建立连接,则可能是网络配置有问题。 #### 2. 远程仓库地址错误 确认远程仓库URL是否正确设置。可以通过运行命令检查当前配置的远程仓库地址[^2]: ```bash git remote -v ``` 如果有误, 可重新设定正确的SSH/HTTPS URL: ```bash git remote set-url origin git@github.com:username/repo.git ``` #### 3. 大文件上传限制 某些平台(如GitHub,GitLab)对于单次提交中的大文件大小有限制。如果存在超出规定尺寸的大文件,可能会导致传输失败。建议安装并启用Git LFS (Large File Storage)[^3], 它专门用于管理大型二进制数据集。 先初始化LFS跟踪特定类型的文件后再执行常规操作即可改善状况: ```bash git lfs install git lfs track "*.psd" git add .gitattributes git add yourfile.psd git commit -m "Add file with LFS support" git push ``` #### 4. 身份认证失效 有时由于令牌过期或者其他安全策略调整造成身份校验不通过也会引发此类现象。此时需更新个人访问token 或者重新生成ssh key 并将其添加到对应的服务器上完成绑定流程[^4]. #### 5. 防火墙代理干扰 企业内部环境下的防火墙规则有可能阻止对外部资源发起的数据交换活动。联系管理员了解具体情况并将必要的端口开放出来有助于恢复正常功能表现[^5]. 以上就是针对“Git一直处于Pushing状态”的一些排查思路和技术手段介绍。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值