C - Push!!

Mr. Schwarz was a famous powerful pro wrestler. He starts a part time job as a warehouseman. His task is to move a cargo to a goal by repeatedly pushing the cargo in the warehouse, of course, without breaking the walls and the pillars of the warehouse.
There may be some pillars in the warehouse. Except for the locations of the pillars, the floor of the warehouse is paved with square tiles whose size fits with the cargo. Each pillar occupies the same area as a tile.
这里写图片描述
Initially, the cargo is on the center of a tile. With one push, he can move the cargo onto the center of an adjacent tile if he is in proper position. The tile onto which he will move the cargo must be one of (at most) four tiles (i.e., east, west, north or south) adjacent to the tile where the cargo is present.
To push, he must also be on the tile adjacent to the present tile. He can only push the cargo in the same direction as he faces to it and he cannot pull it. So, when the cargo is on the tile next to a wall (or a pillar), he can only move it along the wall (or the pillar). Furthermore, once he places it on a corner tile, he cannot move it anymore.
He can change his position, if there is a path to the position without obstacles (such as the cargo and pillars) in the way. The goal is not an obstacle. In addition, he can move only in the four directions (i.e., east, west, north or south) and change his direction only at the center of a tile.
As he is not so young, he wants to save his energy by keeping the number of required pushes as small as possible. But he does not mind the count of his pedometer, because walking is very light exercise for him.
Your job is to write a program that outputs the minimum number of pushes required to move the cargo to the goal, if ever possible.
Input
The input consists of multiple maps, each representing the size and the arrangement of the warehouse. A map is given in the following format.

w h
d11 d12 d13 … d1w
d21 d22 d23 … d2w

dh1 dh2 dh3 … dhw

The integers w and h are the lengths of the two sides of the floor of the warehouse in terms of widths of floor tiles. w and h are less than or equal to 7. The integer dij represents what is initially on the corresponding floor area in the following way.
0:
nothing (simply a floor tile)
1:
pillar
2:
the cargo
3:
the goal
4:
the warehouseman (Mr. Schwarz)
Each of the integers 2, 3 and 4 appears exactly once as dij in the map. Integer numbers in an input line are separated by at least one space character. The end of the input is indicated by a line containing two zeros.
Output
For each map, your program should output a line containing the minimum number of pushes. If the cargo cannot be moved to the goal, `-1’ should be output instead.
Sample Input
5 5
0 0 0 0 0
4 2 0 1 1
0 1 0 0 0
1 0 0 0 3
1 0 0 0 0
5 3
4 0 0 0 0
2 0 0 0 0
0 0 0 0 3
7 5
1 1 4 1 0 0 0
1 1 2 1 0 0 0
3 0 0 0 0 0 0
0 1 0 1 0 0 0
0 0 0 1 0 0 0
6 6
0 0 0 0 0 3
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 2 0 0 0 0
4 0 0 0 0 0
0 0
Sample Output
5
-1
11
8

题意:求箱子到达终点的最少步数。

bfs求解,枚举人的状态从而推出箱子的状态。

代码:

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

using namespace std;

int dx[4]={1,-1,0,0};
int dy[4]={0,0,-1,1};
int vis[8][8][8][8];
int map[8][8];
int m,n;
struct node
{
    int xp,yp,xb,yb;
    int step;
}cur,tmp,gg;

int jud(int x1,int y1)
{
    if(x1>=n||y1>=m||x1<0||y1<0) return 0;

    return 1;
}
int bfs()
{
    queue <node> que;
    que.push(gg);

    int ans=0x3f3f3f3f;

    while(!que.empty())
    {
        tmp=que.front();
        que.pop();

        if(map[tmp.xb][tmp.yb]==3)
        {
            ans=min(ans,tmp.step);
            //箱子被移到终点
        }

        for(int i=0;i<4;i++)
        {
            //枚举人
            cur.xp=tmp.xp+dx[i];
            cur.yp=tmp.yp+dy[i];
            //当前没走过或者当前步数比过往步数少并且是可走的
            if( (vis[cur.xp][cur.yp][tmp.xb][tmp.yb]==-1 || tmp.step<vis[cur.xp][cur.yp][tmp.xb][tmp.yb]) && map[cur.xp][cur.yp]!=1 && jud(cur.xp,cur.yp) )
            {
                if(cur.xp==tmp.xb&&cur.yp==tmp.yb)
                {
                    //当人是箱子的上一状态
                    cur.xb=cur.xp+dx[i];
                    cur.yb=cur.yp+dy[i];
                    if(jud(cur.xb,cur.yb))//箱子可移
                    {
                        cur.step=tmp.step+1;
                        vis[cur.xp][cur.yp][cur.xb][cur.yb]=cur.step;
                        que.push(cur);
                    }
                }

                if(!(cur.xp==tmp.xb&&cur.yp==tmp.yb))
                {
                    //当人不是箱子的上一状态
                    //箱子保持原状态
                    cur.xb=tmp.xb;
                    cur.yb=tmp.yb;
                    cur.step=tmp.step;
                    vis[cur.xp][cur.yp][cur.xb][cur.yb]=cur.step;
                    que.push(cur);
                }
            }
        }
    }

    if(ans==0x3f3f3f3f)
        return -1;
    else
        return ans;

}
int main (void)
{
    while(~scanf("%d %d",&m,&n))
    {
        memset(vis,-1,sizeof(vis));
        if(m==0&&n==0)
            break;

        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++)
            {
                scanf("%d",&map[i][j]);
                if(map[i][j]==4)
                {
                    gg.xp=i;
                    gg.yp=j;
                    map[i][j]=0;
                }
                if(map[i][j]==2)
                {
                    gg.xb=i;
                    gg.yb=j;
                    map[i][j]=0;
                }
            }
        }

        gg.step=0;
        vis[gg.xp][gg.yp][gg.xb][gg.yb]=0;

        int ans=bfs();
        printf("%d\n",ans);
    }
    return 0;
}
<think> 我们正在处理一个关于Git的错误,具体是在执行`git fetch --tags origin`时出现的错误信息: ! [rejected] v1.0.0-push-op-map -> v1.0.0-push-op-map (would clobber existing tag) 这个错误的意思是,Git在获取远程仓库(origin)的标签(tags)时,发现远程有一个标签`v1.0.0-push-op-map`,而本地已经存在同名的标签,但是这两个标签指向的提交不同,因此Git拒绝了获取操作,以避免覆盖(clobber)本地的标签。 解决这个问题的思路通常是:要么强制覆盖本地的标签,要么先删除本地的标签再重新获取,或者检查本地标签是否应该保留(如果本地标签是正确的,那么可能是远程标签有问题,需要协调)。 根据Git的提示,我们可以使用以下命令来强制获取标签并覆盖本地标签(注意:这将覆盖本地同名的标签): ```bash git fetch --tags -f origin ``` 或者,我们也可以先删除本地的这个标签,然后再重新获取: ```bash git tag -d v1.0.0-push-op-map git fetch --tags origin ``` 但是,需要注意的是,如果这个标签是重要的(比如它标记了一个发布版本),那么强制覆盖或删除之前需要确认是否应该覆盖。如果本地的标签是错误的,那么覆盖掉没有问题;如果本地的标签是正确的,而远程的标签是错误的,那么应该通知仓库维护者修正远程标签。 另外,还有一种情况是,这个标签可能是被移动了(即同一个标签名指向了不同的提交),这种情况在协作开发中应该避免,因为标签通常用于标记特定的版本,不应该被移动。如果确实需要移动标签,那么需要团队成员都更新标签。 因此,解决方法如下: 1. **强制获取并覆盖本地标签**(推荐在确认可以覆盖的情况下使用): ```bash git fetch --tags -f origin ``` 2. **删除本地标签后重新获取**: ```bash git tag -d v1.0.0-push-op-map git fetch --tags origin ``` 3. **如果本地标签是正确的,而远程标签是错误的**,那么应该联系仓库维护者,请求删除或修正远程标签。然后你可以在本地删除这个标签(如果不再需要)或者保留。 4. 另外,如果这个标签在本地已经被使用(例如,有基于该标签的发布),那么需要谨慎操作,确保覆盖或删除不会影响工作。 根据引用[2]中提到的类似错误(分支提交冲突)的解决方法,我们也可以类比处理标签冲突。但标签和分支不同,分支可以合并,而标签是静态的,所以通常直接覆盖或删除即可。 **注意**:在执行这些操作之前,请确保你了解覆盖或删除标签的后果,特别是在团队协作环境中。 如果问题仍然存在,可以考虑使用`git fetch --tags --force origin`(与`-f`相同)来强制获取所有标签。 现在,我们生成一些相关问题: </think> ### Git 标签冲突问题分析与解决 #### 错误原因分析 执行 `git fetch --tags origin` 时出现 `! [rejected] v1.0.0-push-op-map -> v1.0.0-push-op-map (would clobber existing tag)` 错误,表示**本地已存在同名标签但指向不同提交对象**。Git 默认拒绝覆盖本地标签,防止意外丢失数据[^2]。 #### 解决方案 ##### 方法一:强制覆盖本地标签(推荐) ```bash git fetch --tags -f origin # 强制覆盖冲突标签 ``` 或 ```bash git fetch origin '+refs/tags/*:refs/tags/*' --force # 精确强制拉取标签 ``` > ✅ 适用场景:确认需使用远程仓库的标签版本 ##### 方法二:手动删除本地冲突标签 ```bash git tag -d v1.0.0-push-op-map # 删除本地冲突标签 git fetch --tags origin # 重新拉取远程标签 ``` > ✅ 适用场景:需先检查本地标签内容再决定是否保留 ##### 方法三:单标签强制更新 ```bash git fetch origin tag v1.0.0-push-op-map --force # 仅强制更新指定标签 ``` #### 根本问题预防 1. **标签命名规范** 使用语义化版本命名(如 `v1.2.3`),避免使用临时名称如 `-push-op-map` 2. **协作流程优化** ```mermaid graph LR A[创建新标签] --> B[立即推送到远程] C[拉取更新] --> D{存在冲突标签?} D -->|是| E[按上述方案解决] D -->|否| F[正常操作] ``` 3. **定期清理无效标签** ```bash git tag -l | xargs git tag -d # 删除所有本地标签 git fetch --tags # 重新拉取最新标签 ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值