P1126 机器人搬重物 bfs 坐标系

题目描述   https://www.luogu.org/problemnew/show/P1126

机器人移动学会(RMI)现在正尝试用机器人搬运物品。机器人的形状是一个直径$1.6米的球。在试验阶段,机器人被用于在一个储藏室中搬运货物。储藏室是一个N \times MN×M的网格,有些格子为不可移动的障碍。机器人的中心总是在格点上,当然,机器人必须在最短的时间内把物品搬运到指定的地方。机器人接受的指令有:向前移动11步(Creep);向前移动2步(Walk);向前移动33步(Run);向左转(Left);向右转(Right)。每个指令所需要的时间为11秒。请你计算一下机器人完成任务所需的最少时间。

输入输出格式

输入格式:

 

第一行为两个正整数N,M(N,M \le 50)N,M(N,M≤50),下面NN行是储藏室的构造,00表示无障碍,11表示有障碍,数字之间用一个空格隔开。接着一行有44个整数和11个大写字母,分别为起始点和目标点左上角网格的行与列,起始时的面对方向(东EE,南SS,西WW,北NN),数与数,数与字母之间均用一个空格隔开。终点的面向方向是任意的。

 

输出格式:

 

一个整数,表示机器人完成任务所需的最少时间。如果无法到达,输出-1−1。

P1126 机器人搬重物 bfs 坐标系

 

输入输出样例

输入样例#1: 复制

9 10
0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 0 1 0
0 0 0 1 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0
0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 1 0 0 0 0
0 0 0 1 1 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 1 0
7 2 2 7 S

输出样例#1: 复制

12

说明,思路比较明朗,但是采坑无数

1.  建立坐标后,沿着x y递增是向右 向下的,和以最下角建立的坐标系不同

2. 机器人是有大小的,因此最外圈都是不能放机器人的,同时障碍的四个角都不能放

3 左西右东  我搞反了  悲催啊。

#include<stdio.h>
#include<functional>
#include<queue>
#include<vector>
#include<iostream>
#include<sstream>
#include<string.h>
#include<set>
using namespace std;
typedef struct {
    int x,y;
    int dir;
    int il;
} node;
node start,last,tnode;
set<int> za; //又来存储障碍顶点
set<int> vs;// 存储处理过的状态,1000x+10y+dir
queue<node> que;
int n,m;
int N,M;
bool isgo=true;
int xx[]= {-1,0,1,0};
int yy[]= {0,1,0,-1};

bool existed(node t)
{

    if(vs.count(1000*t.x+t.y*10+t.dir))
        return true;
    else
    {
        vs.insert(1000*t.x+t.y*10+t.dir);
        return false;
    }

}

void  bfs() {

    if(!isgo) return;

    if(!que.empty())
    {
        tnode=que.front();
        //cout<<tnode.x<<" "<<tnode.y<<" "<<tnode.dir<<" "<<tnode.il<<endl;
        que.pop();
    }
    else
    {
        cout<<-1<<endl;
        isgo=false;
        return;
    }


    if(tnode.x==last.x&&tnode.y==last.y) {
        cout<<tnode.il<<endl;
        isgo=false;
        return;
    } else {
        //处理左右
        node t1=tnode;
        t1.dir=(t1.dir-1+4)%4;
        t1.il++;
        if(!existed(t1))
            que.push(t1);

        node t2=tnode;
        t2.dir=(t2.dir+1)%4;
        t2.il++;
        if(!existed(t2))
            que.push(t2);
        //在某个方向上走3步
        int nx,ny;
        bool iscango=false;
        node t3=tnode;
        {
            nx=t3.x+xx[t3.dir];
            ny=t3.y+yy[t3.dir];
            if(nx>0&&nx<n&&ny>0&&ny<m&&!za.count(nx*M+ny)) {
                t3.il++;
                t3.x=nx;
                t3.y=ny;
                iscango=true;
                if(!existed(t3))
                    que.push(t3);
            }
        }

        node t4=tnode;
        if(iscango) {
            iscango=false;
            nx=nx+xx[t4.dir];
            ny=ny+yy[t4.dir];
            if(nx>0&&nx<n&&ny>0&&ny<m&&!za.count(nx*M+ny)) {
                t4.il++;
                t4.x=nx;
                t4.y=ny;
                iscango=true;
                if(!existed(t4))
                    que.push(t4);
            }
        }

        node t5=tnode;
        if(iscango) {
            iscango=false;
            nx=nx+xx[t5.dir];
            ny=ny+yy[t5.dir];
            if(nx>0&&nx<n&&ny>0&&ny<m&&!za.count(nx*M+ny)) {
                t5.il++;
                t5.x=nx;
                t5.y=ny;
                iscango=true;
                if(!existed(t5))
                    que.push(t5);
            }
        }
        //cout<<"size---"<<que.size()<<endl;
        bfs();
    }


}
int main() {
    cin>>n>>m;
    N=n+1;
    M=m+1;
    int t;
    for(int i=0; i<n; i++)
        for(int j=0; j<m; j++) {
            cin>>t;
            if(t) {
                if(!za.count(i*M+j))
                    za.insert(i*M+j);

                if(!za.count(i*M+j+1))
                    za.insert(i*M+j+1);

                if(!za.count((i+1)*M+j))
                    za.insert((i+1)*M+j);

                if(!za.count((i+1)*M+j+1))
                    za.insert((i+1)*M+j+1);

            }
        }
    cin>>start.x>>start.y;
    cin>>last.x>>last.y;
    char c;
    cin>>c;
    switch(c) {
        case 'E':
            start.dir=1;
            break;
        case 'S':
            start.dir=2;
            break;
        case 'W':
            start.dir=3;
            break;
        case 'N':
            start.dir=0;
            break;
    }
    start.il=0;
    vs.insert(1000*start.x+10*start.y+start.dir);
    que.push(start);
    bfs();

}