In-depth discussion on POJ 2312 Battle City priority queue + BFS

Source: Internet
Author: User

I believe everyone in the tank wars has played it. This question was designed based on this game. Tanks must go from the starting point (Y) to the destination (T). tanks cannot go through the steel wall (S), river (R), or walk in the open space (E ), damage to the brick wall (B) when shooting a brick wall, it does not walk and takes a unit of time, it also takes a unit of time to move up when the open space. How long does it take for a tank to start from the start point to the destination? The output cannot be-1;
A good search question. Because the time spent by the brick walls is different from that of the open space, the general BFS search is not allowed. By using the DFS deep search, you will find that the time is very complicated and will inevitably time out (the maximum is 300*300 of the graph ). This question can be solved using improved wide search or priority queue + bfs or wide Memory search methods.
Method 1: Improved BFS:
Some nodes take two units of time. To use BFS, you have to change it. Because BFS can only be operated one step at a time, either by expansion or by damaging the brick wall. Therefore, you only need to check whether the point is 'B'. If yes, you have to stop. If not, continue to expand. That is to say, the expansion of some points is slow, so from the points in the queue, you can determine which operation to execute.
From this question, I also have a deeper understanding of bfs. "The reason why bfs can find the optimal solution as quickly as possible is that it operates one step at a time (here the operation step is very flexible, for example, if the brick wall is damaged in the question, the while () statement is an operation!" Copy codeThe Code is as follows :/*
In this question, point B requires two steps. Therefore, after point B, you cannot press it into the queue after point B. You need to stop it in the same place and cannot extend it to other points, it is equivalent that he can only expand to himself, so he will press himself into the queue map [x] [y] = 'E' because it is enough to destroy the brick wall once, or next time, or 'B', keep pressing into the queue and stay in the same place
Generally, the "inbound queue" point is considered. This time, whether the "outbound queue" point meets the conditions must be considered!
*/
# Include "iostream"
# Include "queue"
Using namespace std;
Char map [301] [301];
Bool visit [301] [301];
Int dir [4] [2] = {}, {-}, {}, {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') // you need to stop this step.
{
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 for the next Vertex
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' | visit [next. x] [next. y]) // determine whether the next vertex is valid
Continue;
Next. time = start. time + 1;
If (map [next. x] [next. y] = 'T') // reach the destination
Return next. time;
Visit [next. x] [next. y] = 1; // mark the vertices that have passed
Q. push (next );
}
}
}
Return-1;
}
Int main (void)
{
Int I, j;
While (scanf ("% d", & m, & n) = 2)
{
If (m = 0 & n = 0)
Break;
Memset (visit, 0, sizeof (visit); // initialize the status 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 start point
{
Sx = I;
Sy = j;
}
}
}
Printf ("% d \ n", bfs ());
}
System ("pause ");
Return 0;
}

Method 2: priority queue + BFS
The broad search concept is also used, but the process is only performed when the team leaves. The priority queue is used to bring the team out first at the point with the minimum time value from the queue to the start point. This method uses the STL of the priority queue.
First, you need to understand the rules for using the priority queue:
By default, the comparison rules of the elements in the priority queue are sorted by element values in ascending order. That is to say, the largest element in the queue is always at the beginning of the queue, instead of following the first-in-first-out principle, the queue is the largest element in the current queue. This is similar to sorting the elements in the queue from large to small. Of course, you can re-define the comparison rules by reloading the "<" operator.
The function that overload the "<" operator can be written in the struct, or outside the struct. When writing in the external structure, remember that the parameter of the function should be referenced ..
Method 1:
Copy codeCode: struct node
{
Int x, y;
Int step;
};
Priority_queue <node> q; // by default, the comparison rules of elements in the priority queue are sorted by element values in ascending order;
Bool operator <(const node & a, const node & B) // const must be referenced in brackets
{
Return a. step> B. step; // sort data in ascending order. Heavy load is less than the number. Because the default value is from large to small
}

Method 2:
Copy codeCode: struct node
{
Int x, y;
Int time; // defines a priority queue.
Friend bool operator <(node a, node B)
{// ">" Is used for sorting from small to large; "<" is used for sorting from large to small
Return a. time> B. time; // sort from small to large
}
};
Priority_queue <node> q; // by default, the comparison rules of elements in the priority queue are sorted by element values in ascending order;

Remember: ">" is used for sorting from small to large; "<" is used for sorting from large to small;Copy codeThe Code is as follows :/*
The implementation of the priority queue does not need to limit each operation step, but the minimum number of operations is used for each step.
*/
# Include "iostream"
# Include "queue"
Using namespace std;
Char map [301] [301];
Bool visit [301] [301];
Int dir [4] [2] = {}, {-}, {}, {0,-1 }};
Int m, n, sx, sy;
Struct node
{
Int x, y, time; // defines 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 (); // get the head pointer of a queue is different from that of a common Queue (Q. front)
Q. pop ();
For (I = 0; I <4; I ++)
{
Next. x = start. x + dir [I] [0]; // search for the next Vertex
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' | visit [next. x] [next. y]) // determine whether the next vertex is valid
Continue;
If (map [next. x] [next. y] = 'B') // be careful not to be careless here
Next. time = start. time + 2;
Else
Next. time = start. time + 1;
If (map [next. x] [next. y] = 'T') // reach the destination
Return next. time;
Visit [next. x] [next. y] = 1; // mark the vertices that have passed
Q. push (next );
}
}
Return-1;
}
Int main (void)
{
Int I, j;
While (scanf ("% d", & m, & n) = 2)
{
If (m = 0 & n = 0)
Break;
Memset (visit, 0, sizeof (visit); // initialize the status 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 start point
{
Sx = I;
Sy = j;
}
}
}
Printf ("% d \ n", bfs ());
}
System ("pause ");
Return 0;
}

Method 3: memory-based search
Unlike the BFS in the priority queue for processing when it leaves the queue, the memory-wide search is for processing at the point. You do not need to mark a point when searching for a wide memory. You only need to select a point when you join the team. For example, if point A is found, you need to select an adjacent contact that is later than the time value of Point A (which cannot be equal) and update the time value of the joining Point.Copy codeThe Code is 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 }};
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 =;
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", & 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.