【搜索】緊急救援

题目描述

话说2007年8月5日,Mike博士神秘失踪了,最后发现是被外星人绑架了,幸好外星人目前还是在地球上活动,并且知道外星人不了解地球,幸好,Milk博士身上有无线信号发送装置,我们终于确定了他的位置,必须赶快到那里去救他。
根据无线信号发送装置,我们确定出一张地图,为了尽快寻找到Mike博士,于是这个光荣和艰巨的任务便交给了你,编写程序,通过使用一张地图帮助研究所确定从研究所出发找到Mike博士最短距离。
数据范围: n<=1000
输入格式

第一行为n
第二行为n*n的地图(其中0表示通路,1表示死路)
最后两行每行有两个数字,分别表示研究所的坐标和博士信号所在的位置。
输出格式

一个数字k,表示从研究所出发找到Milk博士的最短距离。
样例输入
10
0100110100
0001110010
1000000001
1000100011
0000101100
1000001100
1001010011
0000010100
0101010000
1001000001
1 7
10 2
样例输出
14

一道簡單的廣搜,考察廣搜模板。

ACCode:

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <bitset>

using std::bitset;

const char fi[] = "rqnoj34.in";
const char fo[] = "rqnoj34.out";
const int maxN = 1010;
const int SIZE = 1000000;
const int MAX = 0x3fffff00;
const int MIN = -MAX;
const int dx[] = {0, 0, 1, -1};
const int dy[] = {1, -1, 0, 0};

bitset <maxN> map[maxN];
bitset <maxN> marked[maxN];
short q[SIZE][2];
int level[maxN][maxN];
int n, x1, y1, x2, y2, f, r;
char ch;

  void init_file()
  {
    freopen(fi, "r", stdin);
    freopen(fo, "w", stdout);
  }
    
  void readdata()
  {
    scanf("%d", &n);
    for (int i = 1; i < n + 1; ++i)
    {
      getchar();
      for (int j = 1; j < n + 1; ++j)
      {
        scanf("%c", &ch);
        if (ch == '0')
          map[i].set(j);
      }
    }
    scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
  }
  
  void Enq(int x, int y)
  {
    q[r = (r + 1) % SIZE][0] = x;
    q[r][1] = y;
    marked[x].set(y);
  }
  
  int Deq()
  {
    f = (f + 1) % SIZE;
    return (q[f][0] - 1) * n + q[f][1];
  }
  
  void Bfs()
  {
    while (f != r)
    {
      int Now = Deq();
      int x = (Now - 1) / n + 1;
      int y = (Now - 1) % n + 1;
      for (int j = 0; j < 4; ++j)
      {
        int u = x + dx[j];
        int v = y + dy[j];
        if (u < 1 || u > n || v < 1 || v > n)
          continue;
        if (map[u].test(v) && !marked[u].test(v))
        {
          Enq(u, v);
          level[u][v] = level[x][y] + 1;
        }
        if (u == x2 && v == y2) return;
      }
    }
  }
  
  void work()
  {
    f = r = 0;
    Enq(x1, y1);
    Bfs();
    printf("%d", level[x2][y2]);
  }
  
int main()
{
  init_file();
  readdata();
  work();
  exit(0);
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值