Further discussion on POJ 2312 Battle City Priority Queue +bfs_c language

Source: Internet
Author: User
I believe that the tank war we have played it, the subject is based on this game design. Tank to from beginning (Y), to Destination (T), tanks cannot go through the steel Wall (S), the River (r), can be in the open space in the Walk (E), shooting damage brick wall (B), shooting brick walls do not walk and spend a unit of time, in the open space, also spent a unit of time. Ask the tank from the beginning to the destination at least how much time to spend, not up to output-1;
A good search question. Because of the different time taken by the brick wall and the open space, it is not possible to use the general BFS. With Dfs deep search, you will find that the time is very complex, will be timed out (the largest is 300*300 diagram). the subject can be solved by using the improved extensive search or priority queue +bfs or memory search three ways.
The first method: Improved BFS:
Some nodes need to spend 2 units of time, want to use BFS will have to change, because the BFS can only operate one step at a time, or expand, or destroy the brick wall. So just check that the point is not ' B ', yes, you have to stop a step, if not, continue to expand, that is, some of the expansion of the point of a beat, so from the queue out of the point of the judge to see what action to perform.
From this problem, I also have a deeper understanding of BFS, "BFS is the quickest way to find the best solution, because it is one step at a time (the operation here a step, very flexible, such as the title of the destruction of the brick wall), while () inside the statement is an operation!" ”
Copy Code code as follows:

/*
The B point in this question requires two steps to operate, so encountered after the B point can not +2 directly into the queue, need to stop in situ, can not expand to other points, the equivalent of he can only expand to their own, so he put himself into the queue map[x][y]= ' E ' is because damage to the brick wall once is enough, or next time, or ' B ', constantly pressed into the queue, constantly in situ stay
Usually consider the "into the queue" point, this time to consider the "out of the queue" point whether to meet the conditions!
*/
#include "iostream"
#include "queue"
using namespace Std;
Char map[301][301];
BOOL visit[301][301];
int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
int m,n,sx,sy;
struct node
{
int x,y,time;
};
int BFS ()
{
int i;
Node You,start,next;
queue<node>q;
YOU.X=SX;
You.y=sy;
you.time=0;
Q.push (you);
Visit[sx][sy]=1;
while (!q.empty ())
{
Start=q.front ();
Q.pop ();
if (map[start.x][start.y]== ' B ')//This step requires a stop
{
start.time++;
map[start.x][start.y]= ' E ';
Q.push (start);
}
Else
{
for (i=0;i<4;i++)
{
NEXT.X=START.X+DIR[I][0]; Search Next Point
NEXT.Y=START.Y+DIR[I][1];
if (next.x<0 | | next.y<0 | | next.x>=m | | next.y>=n | | map[next.x][next.y]== ' R ' | | map[next.x][next.y]== ' S | | | v ISIT[NEXT.X][NEXT.Y])//Determine if the next point is legal
Continue
next.time=start.time+1;
if (map[next.x][next.y]== ' T ')//arrival destination
return next.time;
Visit[next.x][next.y]=1; Mark has passed the point
Q.push (next);
}
}
}
return-1;
}
int main (void)
{
int i,j;
while (scanf ("%d%d", &m,&n) ==2)
{
if (m==0 && n==0)
Break
memset (visit,0,sizeof (visit)); Initializing the state of each node
for (i=0;i<m;i++)
{
GetChar ();
for (j=0;j<n;j++)
{
scanf ("%c", &map[i][j]);
if (map[i][j]== ' Y ')//record starting point
{
Sx=i;
Sy=j;
}
}
}
printf ("%d\n", BFS ());
}
System ("pause");
return 0;
}

The second method: Priority Queue +bfs method
is also used in the idea of a wide search, just when the team did the processing, using the priority queue to let the queue to the point of the time value of the lowest point first out of the team. This method uses the STL of the precedence queue.
first you need to understand the rules for using precedence queues:
The comparison rules of the elements in the precedence queue are sorted by the value of the elements from large to small, that is, the largest element in the queue is always at the head of the team, so when the team is out, it is not done according to the FIFO principle, but the largest element in the current queue. This is similar to sorting the elements in a queue from large to small. Of course, you can redefine the comparison rule by overloading the "<" operator.
Overloaded "<" operator functions can be written in the structure, or can be written outside the structure, written in the outside of the structure, remember the parameters of the function to use the reference.
The first method of overloading:
Copy Code code as follows:

struct node
{
int x,y;
int step;
};
priority_queue<node>q; The comparison rules for elements in the precedence queue are sorted by the value of the elements from large to small by default;
BOOL operator< (const node &A,CONST node &b)//parentheses inside is const and must also be referenced
{
Return a.step>b.step; Sort from small to large. Overload is less than the number. Because the default is from big to small
}

The second method of overloading:
Copy Code code as follows:

struct node
{
int x,y;
int time; Define a priority queue
friend bool operator< (Node A, Node B)
{///from small to large sorting using ">"; if you want to sort from large to small, use the "<" number
return a.time> B.time; Sort from small to large
}
};
priority_queue<node>q; The comparison rules for elements in the precedence queue are sorted by the value of the elements from large to small by default;

Remember: from small to large sorting using ">" number, if you want to order from large to small, then use the "<" number;
Copy Code code as follows:

/*
Priority queue implementation is not limited to one step at a time, but each time to take the smallest number of steps to walk
*/
#include "iostream"
#include "queue"
using namespace Std;
Char map[301][301];
BOOL visit[301][301];
int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
int m,n,sx,sy;
struct node
{
int x,y,time; Define a priority queue
friend bool operator< (Node A, Node B)
{
return a.time> B.time; Sort from small to large
}
};
int BFS ()
{
int i;
Node You,start,next;
priority_queue<node>q;
YOU.X=SX;
You.y=sy;
you.time=0;
Q.push (you);
Visit[sx][sy]=1;
while (!q.empty ())
{
Start=q.top (); Take the team head pointer different from the normal queue (Q.front)
Q.pop ();
for (i=0;i<4;i++)
{
NEXT.X=START.X+DIR[I][0]; Search Next Point
NEXT.Y=START.Y+DIR[I][1];
if (next.x<0 | | next.y<0 | | next.x>=m | | next.y>=n | | map[next.x][next.y]== ' R ' | | map[next.x][next.y]== ' S | | | v ISIT[NEXT.X][NEXT.Y])//Determine if the next point is legal
Continue
if (map[next.x][next.y]== ' B ')//Note this is not sloppy
next.time=start.time+2;
Else
next.time=start.time+1;
if (map[next.x][next.y]== ' T ')//arrival destination
return next.time;
Visit[next.x][next.y]=1; Mark has passed the point
Q.push (next);
}
}
return-1;
}
int main (void)
{
int i,j;
while (scanf ("%d%d", &m,&n) ==2)
{
if (m==0 && n==0)
Break
memset (visit,0,sizeof (visit)); Initializing the state of each node
for (i=0;i<m;i++)
{
GetChar ();
for (j=0;j<n;j++)
{
scanf ("%c", &map[i][j]);
if (map[i][j]== ' Y ')//record starting point
{
Sx=i;
Sy=j;
}
}
}
printf ("%d\n", BFS ());
}
System ("pause");
return 0;
}

The Third Way: the memory of a wide search
and priority queue BFS when you are out of the team to do the different is that the memory of the search is at the point of the squad is to do processing. The memory of the wide search does not need to mark the point, just in the team is to pay attention to choice. For example, if the search to a point, to select a point of time than a large number of adjacent points to the team (not equal), and update the time value of the team.
Copy Code code as follows:

#include <string.h>
#include <iostream>
#include <queue>
using namespace Std;
int co,ro,mi,step[305][305];
Char map[305][305],visited[305][305];
int dir[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
typedef struct NODE
{
int x;
int y;
int time;
}node;
BOOL Judge (int x,int y)
{
if (x<0| | y<0| | x>=co| | Y>=ro)
{
return false;
}
if (map[x][y]== ' S ' | | map[x][y]== ' R ')
{
return false;
}
return true;
}
void BFs (int a,int b)
{
int i,x,y,ti;
Node in,out;
queue<node>que;
In.x=a;
In.y=b;
step[a][b]=0;
Que.push (in);
while (!que.empty ())
{
Out=que.front ();
Que.pop ();
visited[out.x][out.y]=0;
for (i=0;i<4;i++)
{
X=OUT.X+DIR[I][0];
Y=OUT.Y+DIR[I][1];
if (!judge (x,y))
Continue
ti=step[out.x][out.y]+1;
if (map[x][y]== ' B ')
ti++;
if (Step[x][y]<=ti)
Continue
Step[x][y]=ti;
if (Visited[x][y])
Continue
Visited[x][y]=1;
In.x=x;
In.y=y;
Que.push (in);
}
}
}
int main ()
{
int i,j,a,b,c,d;
while (scanf ("%d%d", &co,&ro), Co+ro)
{
GetChar ();
for (i=0;i<co;i++)
Gets (Map[i]);
for (i=0;i<co;i++)
for (j=0;j<ro;j++)
{
if (map[i][j]== ' Y ')
{
A=i;
B=j;
}
if (map[i][j]== ' T ')
{
C=i;
D=j;
}
step[i][j]=999999;
}
memset (visited,0,sizeof (visited));
Visited[a][b]=1;
BFS (A,B);
if (step[c][d]!=999999)
printf ("%d\n", Step[c][d]);
Else
printf (" -1\n");
}
return 0;
}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.