BFS专题

C - Nightmare
Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u

Description

Ignatius had a nightmare last night. He found himself in a labyrinth with a time bomb on him. The labyrinth has an exit, Ignatius should get out of the labyrinth before the bomb explodes. The initial exploding time of the bomb is set to 6 minutes. To prevent the bomb from exploding by shake, Ignatius had to move slowly, that is to move from one area to the nearest area(that is, if Ignatius stands on (x,y) now, he could only on (x+1,y), (x-1,y), (x,y+1), or (x,y-1) in the next minute) takes him 1 minute. Some area in the labyrinth contains a Bomb-Reset-Equipment. They could reset the exploding time to 6 minutes. 

Given the layout of the labyrinth and Ignatius' start position, please tell Ignatius whether he could get out of the labyrinth, if he could, output the minimum time that he has to use to find the exit of the labyrinth, else output -1. 

Here are some rules: 
1. We can assume the labyrinth is a 2 array. 
2. Each minute, Ignatius could only get to one of the nearest area, and he should not walk out of the border, of course he could not walk on a wall, too. 
3. If Ignatius get to the exit when the exploding time turns to 0, he can't get out of the labyrinth. 
4. If Ignatius get to the area which contains Bomb-Rest-Equipment when the exploding time turns to 0, he can't use the equipment to reset the bomb. 
5. A Bomb-Reset-Equipment can be used as many times as you wish, if it is needed, Ignatius can get to any areas in the labyrinth as many times as you wish. 
6. The time to reset the exploding time can be ignore, in other words, if Ignatius get to an area which contain Bomb-Rest-Equipment, and the exploding time is larger than 0, the exploding time would be reset to 6. 
 

Input

The input contains several test cases. The first line of the input is a single integer T which is the number of test cases. T test cases follow.
Each test case starts with two integers N and M(1<=N,Mm=8) which indicate the size of the labyrinth. Then N lines follow, each line contains M integers. The array indicates the layout of the labyrinth. 
There are five integers which indicate the different type of area in the labyrinth: 
0: The area is a wall, Ignatius should not walk on it. 
1: The area contains nothing, Ignatius can walk on it. 
2: Ignatius' start position, Ignatius starts his escape from this position. 
3: The exit of the labyrinth, Ignatius' target position. 
4: The area contains a Bomb-Reset-Equipment, Ignatius can delay the exploding time by walking to these areas. 
 

Output

For each test case, if Ignatius can get out of the labyrinth, you should output the minimum time he needs, else you should just output -1. 
 

Sample Input

     
     
3 3 3 2 1 1 1 1 0 1 1 3 4 8 2 1 1 0 1 1 1 0 1 0 4 1 1 0 4 1 1 0 0 0 0 0 0 1 1 1 1 4 1 1 1 3 5 8 1 2 1 1 1 1 1 4 1 0 0 0 1 0 0 1 1 4 1 0 1 1 0 1 1 0 0 0 0 3 0 1 1 1 4 1 1 1 1 1
 

Sample Output

     
     
4 -1 13


代码:

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include<vector>
#include<queue>
#include<stack>
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;

#define MaxSize 10
#define inf 0x3f3f3f3f

int d[4][2]= {1,0,-1,0,0,-1,0,1};

int t,n,m,flag,mp[MaxSize][MaxSize];

struct node
{
  int step,time,x,y;
};

void bfs(int x, int y)
{
  queue<node>q;

  node p,s;

  p.x=x;
  p.y=y;
  p.step=0;
  p.time=6;

  q.push(p);

  while(!q.empty())
    {
      p=q.front();
      q.pop();

      for(int i=0; i<4; i++)
        {
          s.x=p.x+d[i][0];
          s.y=p.y+d[i][1];
          s.step=p.step+1;
          s.time=p.time-1;

          if(s.x<0||s.x>=n||s.y<0||s.y>=m||mp[s.x][s.y]==0||s.time==0) continue;

          if(mp[s.x][s.y]==3)
            {
              printf("%d\n",s.step);
              flag=0;
              return;
            }

          if(mp[s.x][s.y]==4)
            {
              s.time=6;
              mp[s.x][s.y]=1;
            }

          //printf("mp[%d][%d] step=%d time=%d\n",s.x,s.y,s.step,s.time);
          q.push(s);
        }
    }

}

int main()
{
  int T,start_x,start_y;

  scanf("%d",&T);

  while(T--)
    {
      scanf("%d%d",&n,&m);

      for(int i=0; i<n; i++)
        {
          for(int j=0; j<m; j++)
            {
              scanf("%d",&mp[i][j]);

              if(mp[i][j]==2)
                {
                  start_x=i;
                  start_y=j;
                }
            }
        }

      flag=1;

      bfs(start_x,start_y);

      if(flag) printf("-1\n");
    }
  return 0;
}//FROM CJZ



注意点:


第一个注意点:不能用book标记来让走过的点不能再走。

情况1:

1 2 1 1 1 1 1 4 
1 0 0 0 1 0 0 1 
1 4 1 0 1 1 0 1 
1 0 0 0 0 3 0 1 
1 1 4 1 1 1 1 1

假如走到第一列的4左边,如果book标记的话,进去time重设为6之后就困死在里面了(因为前面的1已经走过了)。然而事实上可以进去吃掉4之后再出来。

情况2:

2 1 0 1 1 1 
1 0 0 1 0 1
1 4 1 1 0 1
1 0 0 0 0 1
1 1 1 1 1 3

假如用book标记,走到4那里之后只能从右边走,绕一大圈,最后走不到3就没时间爆炸了。但是事实上,可以吃了4再出来,从左下走,就能到达3。


第二个需要注意的地方:不能简单地仅仅是去掉book就行了。

比如两个4离得很近,在6步以内,那么这两个点永远都会在bfs队列里面来回跑。所以,4遇到一次之后就应该把原来的数值改成1。(仔细想一想为什么是用改数值的方法来解决这个问题:1、每次你去逛一圈回来我又给你把time加到6,那就死循环了(游手好闲的点)2、有一个点找到4就足够了。根据bfs性质,第一个找到的,一定是路径最短的,我找到了4,就进入了队列。在我之后再找到4的点,路径肯定比我长,要你也没用。所以第一次遇到4,加入队列之后,数值就可以改成1了)。


这里不用担心不book会有无穷多个点在队列里,因为每个点身上都绑了个定时炸弹,到处乱跑时间会慢慢减成0,自己就爆掉了。最终剩下的就是走正确路径的。


体会:

这种身上有定时炸弹的bfs可以不用book标记,同理,有步数限制的bfs也不用。


我觉得不用book[i][j]的情况有:

1、再次回到这个点的时候除了步数之外的状态发生了变化(比如time(充值或者自减),身上的钥匙变化),这里可以开三维数组来book,前两个存位置,后一个存状态,比如book[i][j][key]。

2、会被客观性剪枝减掉,比如之前的定时炸弹和步数限制。




E - Rescue
Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u

Description

Angel was caught by the MOLIGPY! He was put in prison by Moligpy. The prison is described as a N * M (N, M <= 200) matrix. There are WALLs, ROADs, and GUARDs in the prison. 

Angel's friends want to save Angel. Their task is: approach Angel. We assume that "approach Angel" is to get to the position where Angel stays. When there's a guard in the grid, we must kill him (or her?) to move into the grid. We assume that we moving up, down, right, left takes us 1 unit time, and killing a guard takes 1 unit time, too. And we are strong enough to kill all the guards. 

You have to calculate the minimal time to approach Angel. (We can move only UP, DOWN, LEFT and RIGHT, to the neighbor grid within bound, of course.) 
 

Input

First line contains two integers stand for N and M. 

Then N lines follows, every line has M characters. "." stands for road, "a" stands for Angel, and "r" stands for each of Angel's friend. 
‘x’是guard,‘#’是墙。

Process to the end of the file. 
 

Output

For each test case, your program should output a single integer, standing for the minimal time needed. If such a number does no exist, you should output a line containing "Poor ANGEL has to stay in the prison all his life." 
 

Sample Input

     
     
7 8 #.#####. #.a#..r. #..#x... ..#..#.# #...##.. .#...... ........
 

Sample Output

     
     
13


代码:

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include<vector>
#include<queue>
#include<stack>
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;

#define MaxSize 205
#define inf 0x3f3f3f3f

char mp[MaxSize][MaxSize];
int book[MaxSize][MaxSize];
int n,m,flag;

int d[4][2]= {1,0,0,1,-1,0,0,-1};

struct node
{
  int x,y,time,kill_guard;

  node()
  {
    kill_guard=0;
  }

};


void bfs(int x, int y)
{
  node p,s;
  queue<node>q;

  p.x=x;
  p.y=y;
  p.time=0;
  book[x][y]=1;

  q.push(p);

  while(!q.empty())
    {
      p=q.front();
      q.pop();

      if(mp[p.x][p.y]=='a')
        {
          flag=0;
          printf("%d\n",p.time);
          return;
        }

      if(mp[p.x][p.y]=='x'&&p.kill_guard==0)
        {
          p.time++;//砍怪花的时间
          p.kill_guard++;
          q.push(p);
        }

      else
        {
          for(int i=0; i<4; i++)
            {
              s.x=p.x+d[i][0];
              s.y=p.y+d[i][1];
              s.time=p.time+1;

              if(s.x<0||s.x>=n||s.y<0||s.y>=m||mp[s.x][s.y]=='#'||book[s.x][s.y]==1) continue;

              book[s.x][s.y]=1;
              q.push(s);
            }
        }

    }
}

int main()
{
  int start_x,start_y;

  while(~scanf("%d%d",&n,&m))
    {

      getchar();

      for(int i=0; i<n; i++)
        {

          for(int j=0; j<m; j++)
            {
              scanf("%c",&mp[i][j]);

              if(mp[i][j]=='r')
                {
                  start_x=i;
                  start_y=j;
                }
            }
          getchar();
        }

      flag=1;
      memset(book,0,sizeof(book));

      bfs(start_x,start_y);

      if(flag)
        printf("Poor ANGEL has to stay in the prison all his life.\n");
    }
  return 0;
}//FROM CJZ



出题人坑得一比,题目对‘x’和‘#’描述缺失。

没仔细读完input,wa了之后才去仔细看input描述,发现是多组数据,需要仔细。



F - Knight Moves
Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u

Description

A friend of you is doing research on the Traveling Knight Problem (TKP) where you are to find the shortest closed tour of knight moves that visits each square of a given set of n squares on a chessboard exactly once. He thinks that the most difficult part of the problem is determining the smallest number of knight moves between two given squares and that, once you have accomplished this, finding the tour would be easy. 
Of course you know that it is vice versa. So you offer him to write a program that solves the "difficult" part. 

Your job is to write a program that takes two squares a and b as input and then determines the number of knight moves on a shortest route from a to b. 
 

Input

The input file will contain one or more test cases. Each test case consists of one line containing two squares separated by one space. A square is a string consisting of a letter (a-h) representing the column and a digit (1-8) representing the row on the chessboard. 
 

Output

For each test case, print one line saying "To get from xx to yy takes n knight moves.". 
 

Sample Input

     
     
e2 e4 a1 b2 b2 c3 a1 h8 a1 h7 h8 a1 b1 c3 f6 f6
 

Sample Output

     
     
To get from e2 to e4 takes 2 knight moves. To get from a1 to b2 takes 4 knight moves. To get from b2 to c3 takes 2 knight moves. To get from a1 to h8 takes 6 knight moves. To get from a1 to h7 takes 5 knight moves. To get from h8 to a1 takes 6 knight moves. To get from b1 to c3 takes 1 knight moves. To get from f6 to f6 takes 0 knight moves.




没什么要说的,就是注意一下输入的处理。


代码:

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include<vector>
#include<queue>
#include<stack>
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;

#define MaxSize 10
#define inf 0x3f3f3f3f

int mp[MaxSize][MaxSize];
int book[MaxSize][MaxSize];
char s1[5],s2[5];
int d[8][2]={2,1,-2,1,2,-1,-2,-1,1,2,-1,2,1,-2,-1,-2};

struct node
{
   int x,y,step;
};


void bfs(int x1,int y1,int x2,int y2)
{
    node t,s;
    queue<node>q;

    s.x=x1;
    s.y=y1;
    s.step=0;
    book[x1][y1]=1;

    q.push(s);

    while(!q.empty())
    {
        t=q.front();
        q.pop();

        if(t.x==x2&&t.y==y2)
        {
            printf("To get from %s to %s takes %d knight moves.\n",s1,s2,t.step);
            return;
        }

        for(int i=0;i<8;i++)
        {
            s.x=t.x+d[i][0];
            s.y=t.y+d[i][1];
            s.step=t.step+1;

            if(s.x<1||s.x>8||s.y<1||s.y>8||book[s.x][s.y]==1) continue;

            book[s.x][s.y]=1;
            q.push(s);
        }
    }
}

int main()
{
    int x1,x2,y1,y2;
    while(~scanf("%s%s",s1,s2))
    {
        x1=s1[0]-'a'+1;
        y1=s1[1]-'0';

        x2=s2[0]-'a'+1;
        y2=s2[1]-'0';

        memset(book,0,sizeof(book));

        bfs(x1,y1,x2,y2);
    }
  return 0;
}//FROM CJZ



H - Find a way
Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u

Description

Pass a year learning in Hangzhou, yifenfei arrival hometown Ningbo at finally. Leave Ningbo one year, yifenfei have many people to meet. Especially a good friend Merceki. 
Yifenfei’s home is at the countryside, but Merceki’s home is in the center of city. So yifenfei made arrangements with Merceki to meet at a KFC. There are many KFC in Ningbo, they want to choose one that let the total time to it be most smallest. 
Now give you a Ningbo map, Both yifenfei and Merceki can move up, down ,left, right to the adjacent road by cost 11 minutes. 
 

Input

The input contains multiple test cases. 
Each test case include, first two integers n, m. (2<=n,m<=200). 
Next n lines, each line included m character. 
‘Y’ express yifenfei initial position. 
‘M’    express Merceki initial position. 
‘#’ forbid road; 
‘.’ Road. 
‘@’ KCF 
 

Output

For each test case output the minimum total time that both yifenfei and Merceki to arrival one of KFC.You may sure there is always have a KFC that can let them meet.
 

Sample Input

     
     
4 4 Y.#@ .... .#.. @..M 4 4 Y.#@ .... .#.. @#.M 5 5 Y..@. .#... .#... @..M. #...#
 

Sample Output

     
     
66 88 66



注意点:

1、有可能某个KFC二个人中只有一人能到达,所以第二个人遇到了KFC时候,不能直接totoal_step加上就去和ans比较(因为也许第一个人并没有走到这一点)。所以要判断。

2、这题目描述不精确,也没说过走的时候能不能经过另一个人的家,不过我后来测试过,不book标记另一个人的家(即可以通过另一个人的家)也能ac。

3、total_step这个参数不能丢到结构体里面,因为第二次bfs构建新点进入队列的时候,所有参数值重新构建,值的根源都是来自第一个点,所以无法保存某个点的total_step的值。所以只有用图来存了,当然也可以把图弄成结构体,book和total_step都扔进去。

4、这里我们可以看到,并不是所有bfs找到目标之后就return。要看题意。



代码:

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include<vector>
#include<queue>
#include<stack>
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;

#define MaxSize 205
#define inf 0x3f3f3f3f

char mp[MaxSize][MaxSize];
int ans,n,m;
int totoal_step[MaxSize][MaxSize];
int book[MaxSize][MaxSize];
int d[4][2]={1,0,0,1,-1,0,0,-1};

struct node
{
	int x,y,step;
};


void bfs(int x, int y)
{
    node t,s;
    queue<node>q;

    t.x=x;
    t.y=y;
    t.step=0;

    q.push(t);

    while(!q.empty())
    {
        t=q.front();
        q.pop();

        if(mp[t.x][t.y]=='@')
        {
            if(totoal_step[t.x][t.y]==0)
            {
                totoal_step[t.x][t.y]+=t.step;
            }
            else
            {
                totoal_step[t.x][t.y]+=t.step;

                ans=min(ans,totoal_step[t.x][t.y]);
            }
        }

        for(int i=0;i<4;i++)
        {
            s.x=t.x+d[i][0];
            s.y=t.y+d[i][1];
            s.step=t.step+1;

            if(s.x<0||s.x>=n||s.y<0||s.y>=m||book[s.x][s.y]==1||mp[s.x][s.y]=='#') continue;

            book[s.x][s.y]=1;
            q.push(s);


        }
    }
}

int main()
{

  while(~scanf("%d%d",&n,&m))
    {
        int x1,x2,y1,y2;

        getchar();

        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++)
            {
                scanf("%c",&mp[i][j]);

                if(mp[i][j]=='Y')
                {
                    x1=i;
                    y1=j;
                }

                if(mp[i][j]=='M')
                {
                    x2=i;
                    y2=j;
                }
            }
            getchar();
        }

        ans=inf;
        memset(totoal_step,0,sizeof(totoal_step));

        memset(book,0,sizeof(book));
        book[x1][y1]=1;
        bfs(x1,y1);

        memset(book,0,sizeof(book));
        book[x1][y1]=1;
        book[x2][y2]=1;
        bfs(x2,y2);

        printf("%d\n",ans*11);
    }
  return 0;
}//FROM CJZ









J - 胜利大逃亡
Time Limit:2000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u

Description

Ignatius被魔王抓走了,有一天魔王出差去了,这可是Ignatius逃亡的好机会. 

魔王住在一个城堡里,城堡是一个A*B*C的立方体,可以被表示成A个B*C的矩阵,刚开始Ignatius被关在(0,0,0)的位置,离开城堡的门在(A-1,B-1,C-1)的位置,现在知道魔王将在T分钟后回到城堡,Ignatius每分钟能从一个坐标走到相邻的六个坐标中的其中一个.现在给你城堡的地图,请你计算出Ignatius能否在魔王回来前离开城堡(只要走到出口就算离开城堡,如果走到出口的时候魔王刚好回来也算逃亡成功),如果可以请输出需要多少分钟才能离开,如果不能则输出-1. 



 

Input

输入数据的第一行是一个正整数K,表明测试数据的数量.每组测试数据的第一行是四个正整数A,B,C和T(1<=A,B,C<=50,1<=T<=1000),它们分别代表城堡的大小和魔王回来的时间.然后是A块输入数据(先是第0块,然后是第1块,第2块......),每块输入数据有B行,每行有C个正整数,代表迷宫的布局,其中0代表路,1代表墙.(如果对输入描述不清楚,可以参考Sample Input中的迷宫描述,它表示的就是上图中的迷宫) 

特别注意:本题的测试数据非常大,请使用scanf输入,我不能保证使用cin能不超时.在本OJ上请使用Visual C++提交. 
 

Output

对于每组测试数据,如果Ignatius能够在魔王回来前离开城堡,那么请输出他最少需要多少分钟,否则输出-1. 
 

Sample Input

     
     
1 3 3 4 20 0 1 1 1 0 0 1 1 0 1 1 1 1 1 1 1 1 0 0 1 0 1 1 1 0 0 0 0 0 1 1 0 0 1 1 0
 

Sample Output

     
     
11


这道题有毒,我在少写一个s.step>t剪枝就直接wa,还不是tle,真是醉。我ac的代码拿去再交几次,有时候a,有时候tle,醉啊。到底是数据坑还是oj坑?反正重点不在这里,这道题很简单,就是把二维图的思想转换成三维。


代码:

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include<vector>
#include<queue>
#include<stack>
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;

#define MaxSize 55
#define inf 0x3f3f3f3f

int flag,a,b,c,time;
int mp[MaxSize][MaxSize][MaxSize];
int book[MaxSize][MaxSize][MaxSize];
int d[6][3]= {1,0,0,-1,0,0,0,1,0,0,-1,0,0,0,1,0,0,-1};

struct node
{
  int x,y,z,step;
};

void bfs(int x, int y, int z)
{
  node t,s;
  queue<node>q;

  t.x=x;
  t.y=y;
  t.z=z;
  t.step=0;
  book[x][y][z]=1;

  q.push(t);

  while(!q.empty())
    {
      t=q.front();
      q.pop();

      if(t.x==a-1&&t.y==b-1&&t.z==c-1)
        {
          if(t.step<=time) printf("%d\n",t.step);

          flag=0;
          return;
        }

      for(int i=0; i<6; i++)
        {
          s.x=t.x+d[i][0];
          s.y=t.y+d[i][1];
          s.z=t.z+d[i][2];
          s.step=t.step+1;

          if(s.x<0||s.x>=a||s.y<0||s.y>=b||s.z<0||s.z>=c||mp[s.x][s.y][s.z]==1||book[s.x][s.y][s.z]==1||s.step>time) continue;

          book[s.x][s.y][s.z]=1;
          q.push(s);
        }
    }
}

int main()
{
  int T;

  scanf("%d",&T);

  while(T--)
    {
      scanf("%d%d%d%d",&a,&b,&c,&time);

      for(int i=0; i<a; i++)
        {
          for(int j=0; j<b; j++)
            {
              for(int k=0; k<c; k++)
                {
                  scanf("%d",&mp[i][j][k]);
                }
            }
        }

      flag=1;
      memset(book,0,sizeof(book));
      bfs(0,0,0);

      if(flag) printf("-1\n");
    }
  return 0;
}//FROM CJZ








K - 迷宫问题
Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%lld & %llu

Description

定义一个二维数组: 
int maze[5][5] = {

	0, 1, 0, 0, 0,

	0, 1, 0, 1, 0,

	0, 0, 0, 0, 0,

	0, 1, 1, 1, 0,

	0, 0, 0, 1, 0,

};

它表示一个迷宫,其中的1表示墙壁,0表示可以走的路,只能横着走或竖着走,不能斜着走,要求编程序找出从左上角到右下角的最短路线。

Input

一个5 × 5的二维数组,表示一个迷宫。数据保证有唯一解。

Output

左上角到右下角的最短路径,格式如样例所示。

Sample Input

0 1 0 0 0
0 1 0 1 0
0 0 0 0 0
0 1 1 1 0
0 0 0 1 0

Sample Output

(0, 0)
(1, 0)
(2, 0)
(2, 1)
(2, 2)
(2, 3)
(2, 4)
(3, 4)
(4, 4)


代码:

思路很简单,就是走到每一点的的时候把它的父节点存下来,最后回溯回去就行了。就是BFS+回溯,模板题。

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include<vector>
#include<queue>
#include<stack>
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;

#define MaxSize 10
#define inf 0x3f3f3f3f
#define LL long long int

int mp[MaxSize][MaxSize];
int book[MaxSize][MaxSize];

int d[4][2]={1,0,0,1,-1,0,0,-1};

struct node
{
    int x,y;
};

struct pre_node
{
    int x,y;
}pre[MaxSize][MaxSize];

void bfs()
{
    queue<node>q;

    node s,e;

    s.x=0;
    s.y=0;
    book[s.x][s.y]=1;


    q.push(s);

    while(!q.empty())
    {
        e=q.front();
        q.pop();

        if(e.x==4 && e.y==4)
        {
            stack<node>sta;

            int a=e.x;
            int b=e.y;

            while(!(a==0 && b==0))
            {
                s.x=a;
                s.y=b;

                sta.push(s);

                a=pre[s.x][s.y].x;
                b=pre[s.x][s.y].y;
            }

            printf("(0, 0)\n");

            while(!sta.empty())
            {
                s=sta.top();

                printf("(%d, %d)\n",s.x,s.y);

                sta.pop();
            }

            return;
        }

        for(int i=0;i<4;i++)
        {
            s.x=e.x+d[i][0];
            s.y=e.y+d[i][1];

            if(s.x<0 || s.x>5 || s.y<0 || s.y>5 || book[s.x][s.y]==1 || mp[s.x][s.y]==1) continue;

            book[s.x][s.y]=1;

            pre[s.x][s.y].x=e.x;
            pre[s.x][s.y].y=e.y;

            q.push(s);
        }
    }

}


int main()
{

  for(int i=0; i<5; i++)
    {
      for(int j=0; j<5; j++)
        {
          scanf("%d",&mp[i][j]);
        }
    }

  bfs();

  return 0;
}//FROM CJZ





C - Catch That Cow
Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%lld & %llu

Description

Farmer John has been informed of the location of a fugitive cow and wants to catch her immediately. He starts at a point N (0 ≤ N ≤ 100,000) on a number line and the cow is at a point K (0 ≤ K ≤ 100,000) on the same number line. Farmer John has two modes of transportation: walking and teleporting.

* Walking: FJ can move from any point X to the points - 1 or + 1 in a single minute
* Teleporting: FJ can move from any point X to the point 2 × X in a single minute.

If the cow, unaware of its pursuit, does not move at all, how long does it take for Farmer John to retrieve it?

Input

Line 1: Two space-separated integers:  N and  K

Output

Line 1: The least amount of time, in minutes, it takes for Farmer John to catch the fugitive cow.

Sample Input

5 17

Sample Output

4

Hint

The fastest way for Farmer John to reach the fugitive cow is to move along the following path: 5-10-9-18-17, which takes 4 minutes.



一道很神奇的bfs题,感觉很新颖,做起来好爽。

代码:
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include<vector>
#include<queue>
#include<stack>
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;

#define MaxSize 200005
#define inf 0x3f3f3f3f
#define LL long long int

int book[MaxSize];

struct node
{
  int num,step;
};

int main()
{
  int a,b;
  memset(book,0,sizeof(book));

  scanf("%d%d",&a,&b);

  queue<node>q;
  node s,e;

  s.num=a;
  s.step=0;

  q.push(s);

  while(!q.empty())
    {
      e = q.front();
      q.pop();

      if(e.num == b)
        {
          printf("%d\n",e.step);
          break;
        }

      s.step = e.step+1;

      /
      s.num = e.num - 1;

      if(!((a<b && s.num-b>=b-a) || (a>b && s.num>a) || s.num<0 || book[s.num]==1))
        {
          book[s.num]=1;

          q.push(s);
        }
        
      ///
      s.num = e.num + 1;

      if(!((a<b && s.num-b>=b-a) || (a>b && s.num>a) || s.num<0 || book[s.num]==1))
        {
          book[s.num]=1;

          q.push(s);
        }
        
      ///
      s.num = e.num * 2;

      if(!((a<b && s.num-b>=b-a) || (a>b && s.num>a) || s.num<0 || book[s.num]==1))
        {
          book[s.num]=1;

          q.push(s);
        }
    }

  return 0;
}//FROM CJZ


  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值