zoukankan      html  css  js  c++  java
  • poj 1376 机器人广搜

    /*郁闷了好久,才理解了此题,

    参考了几位大神的代码才写出了自己的,希望可以对后来者有所帮助

    这道题题意并不难理解,但是是在处理数据时时感到不会;

    题中说一个机器人从给定的起始坐标点到给定的终点坐标点;

    需要注意的是

    1.机器人所走的是图的路线,而数据所给的是图框中的值,所以

    输入时应对数据进行处理,把数据还原成先前的“图”;

    2,机器人是有体积的,胖胖的,所以要注意不要让机器人走边界(题目描述有问题)

    3.题目中涉及了 机器人 走路的 步数(可以走 1, 2 , 3 步)问题,注意如果第一步不能走,那么后面两步

    也走不通,所以应该一步一步的判断走

    方向问题,可以从现在的方向向左转向右转,每次转90度,不能一次转两下,会出错的!

    障碍物问题 (这个用个标记数组就可以解决了)

    最后如果 没有发现就返回 一个值   -1;

    代码效率不是很高,希望以后能学的更多了再来改进

    */

    #include <iostream>
    #include <queue>
    #include<string>
    #include<fstream>
    using namespace std;
    int n,m;
    int res;
    int map[61][61];
    int flag[61][61][4];//标记数组,第三个数据是记录方向的

    string s;

    int bmp[4][2] = {{0,1},{1,0},{0,-1},{-1,0}};//记录上下左右四个方向的辅助数组

    int dl[4] = {3,0,1,2}; //向左转
    int dr[4] = {1,2,3,0};//向右转

    struct node
    {
    int x,y;
    int t;             //t用来 记录搜索步数
    int d;           // d 用来记录方向的
    };

    node first,last,nexta,firstone;

    queue<node> vi;
    int check(int x,int y)   // 判断是否在符合要求的图内
    {
    if(x > 0 && x < n && y > 0 && y < m )
    return true;
    return false;
    }


    int bfs()
    {

    memset(flag,0,sizeof(flag));
    while(!vi.empty())
    {
    node fnode = vi.front();
    vi.pop();
    firstone.x = fnode.x;
    firstone.y = fnode.y;
    firstone.d = fnode.d;
    firstone.t = fnode.t;
    if(firstone.x == last.x && firstone.y == last.y)  // 判断返回值 和 目标相等 则 返回值 
    {
    res = firstone.t;
    return true;
    }
    //cout<<x<<" "<<y<<" "<<de<<" "<<t<<endl;
    int px,py;
    node rnode;

    // 下面这个for循环 是记录 机器人 所走步数 的(1,2,3)

    // 朝所在方向


    for(int j = 1; j <= 3; j++)  
    {
    px = firstone.x + j * bmp[firstone.d][0];
    py = firstone.y + j * bmp[firstone.d][1];

    if(map[px][py] == 1)
    break;
    if(check(px,py) && map[px][py] == 0 && flag[px][py][firstone.d] == 0)
    {
    rnode.x = px;
    rnode.y = py;
    rnode.d = firstone.d;
    rnode.t = firstone.t+1;
    flag[px][py][firstone.d] = 1;
    vi.push(rnode);
    }
    }

    // 往左方向 转


    if(map[firstone.x][firstone.y]==0 && flag[firstone.x][firstone.y][dl[firstone.d]]==0)
    {
    flag[firstone.x][firstone.y][dl[firstone.d]]=1;
    rnode.x = firstone.x;
    rnode.y = firstone.y;
    rnode.t = firstone.t+1;
    rnode.d = dl[firstone.d];
    vi.push(rnode);
    }

    向右 转


    if(map[firstone.x][firstone.y]==0&&flag[firstone.x][firstone.y][dr[firstone.d]]==0)
    {
    flag[firstone.x][firstone.y][dr[firstone.d]]=1;
    rnode.x = firstone.x;
    rnode.y = firstone.y;
    rnode.t = firstone.t+1;
    rnode.d = dr[firstone.d];
    vi.push(rnode);
    }
    }
    return 0;
    }
    int main()
    {
    int a;

    ifstream cin("in.txt");
    while(cin>>n>>m,n+m)
    {
    while(!vi.empty())
    vi.pop();
    memset(flag,0,sizeof(flag));
    memset(map,0,sizeof(map));
    for(int i = 0; i < n ;i++)
    {
    for(int j = 0 ; j < m; j++)
    {
    cin>>a;
    if(a)
    {
    map[i][j] = 1;
    map[i][j+1] = 1;
    map[i+1][j] = 1;
    map[i+1][j+1] = 1;
    }
    }
    }

    cin>>first.x>>first.y>>last.x>>last.y>>s;
    int dire;
    if(s == "east")dire = 0;
    if(s == "south")dire = 1;
    if(s == "west")dire = 2;
    if(s == "north")dire = 3;

    first.t = 0;first.d = dire;

    vi.push(first);
    res = 0;
    flag[first.x][first.y][dire] = 1;
    if(bfs())
    cout<<res<<endl;
    else
    cout<<-1<<endl;
    }
    return 0;
    }

  • 相关阅读:
    遍历及线索化二叉树
    二叉树
    程序的内存布局
    C语言一些易混淆的概念
    C语言标准库函数memcpy和memmove的区别以及内存重叠问题处理
    柔性数组
    一个基于QT简单登录对话框(带验证码功能)
    Qt中的布局管理器
    Qt中的标准对话框
    一个基于QT简单登录对话框
  • 原文地址:https://www.cnblogs.com/lfyy/p/2785081.html
Copyright © 2011-2022 走看看