Zoj1505 solitaire-bidirectional search

Source: Internet
Author: User

This is my first two-way wide search. After referring to Yang's ideas, I finally wrote a two-way wide search under Yang's aura. The idea is the same as that of the instructor, but the stl of c ++ is used. Here we will load the instructor's explanation.

03:40:42 Accepted 1505 C ++. 63 1648 K Tiaotiao

It is now 03:45 am. This victory is really hard to come by. When I am about to collapse, my eyes are suddenly bright ~ AC! It's really a time to go back to the road... :) next I will go into the subject. The problem solved this time is that when time and space are quite difficult, I used the legendary tedious two-way search and wrote it once in high school, later, I thought this thing was a useless vase like a clue binary tree and never touched it again .. I couldn't think of writing two-way and wide-searching, but I also learned a lot of skills.

Zju1505 Solitaire
Question:
On an 8*8 board, four identical chess pieces can move one of them to the left and right sides each time. If there is a barrier, you can skip a chess piece. according to such a moving rule, ask if you can move from a given checkerboard status to another status within 8 steps. time Limit: 10 s

Analysis:
The question seems very clear, and a typical wide search model. deep Search is also very convenient if it is convenient to determine the weight. however, after careful consideration, although there are only eight steps, the number of statuses is quite large. if you do not consider determining the weight, you can select four pieces in each step. Each piece can have four directions, that is, there are 16 possibilities for each step, and there are 16 ^ 8 types of 8 steps in total, that is, about 4*10 ^ 9 types... think about it .. | therefore, the task with heavy weight is very important. there is also a trick to express the status of each board. because the pawns are the same, the Four pawns have eight coordinates in total, so I used to sort the Four pawns by coordinate and convert them into an int type. however, according to the consistent weighting method, we need to open an array about 9*10 ^ 8... so we lost our heavy-duty solution again ..

So I searched the internet and found someone using the legendary two-way search. because each layer of the search can be expanded quite quickly, if two-way search is used, the search will be completed as long as the branches on both sides have intersections. Otherwise, the search on both sides only needs to be extended by Layer 4! In this case, if you do not consider the weight, the total number of extended nodes is 2*16 ^ 4, which is about 13*10 ^ 4, which is completely acceptable! The space problem is solved !. However, I still have some concerns in terms of time. But in this case, I can't care so much about it. I suddenly went out for a fight. I didn't expect it to be an AC, and the time was 0.63s, so I was quite satisfied.

In the process of Bidirectional wide search, we encountered such issues.
1. How do I search in turn?
You do not need to write the code twice. the two BFs arrays are A and B. The included Cursor Is Pa, QA, Pb, and QB. when the front node is expanded, the and B names are exchanged, and the p and q cursors are exchanged. how to exchange a and B? Hey, use A0 and B0 to open the array, and declare a and B as the pointer type!
2. How to determine the weight? And judge whether the search is complete?
The most stupid method I use. because each time a is used as the current array and B is the array of the other party, the weight is scanned in all States before; to determine the intersection, scan all the States before B...> _ <|
3. How can I skip a pawn?
In fact, whether to skip the pawns is only related to the current status. Therefore, this problem can be well solved by adding a judgment.
4. How do I deal with 'within 8 step '?
When the number of nodes to be expanded in a certain direction is already four steps, the number of nodes to be expanded after the start is also four steps. therefore, nodes in this direction do not need to be extended. so now we only need to expand the nodes of the other party. during implementation, you can use a flag to indicate whether the direction can be switched.

Summary:
Direct wide search and deep search fail, and the greatest difficulty lies in the large number of States, so it cannot be directly hashed. by using Bidirectional wide search, the search layers are reduced by half. Reducing one layer at a very fast speed can also bring unexpected benefits. in general, two-way wide-search saves a lot of status compared to classic wide-search, but it is a waste of time to judge the intersection.

This article from the csdn blog, reproduced please indicate the source: http://blog.csdn.net/tiaotiaoyly/archive/2007/08/01/1720450.aspx

Attach your own code:

# Include <cstdio> <br/> # include <cstring> <br/> # include <iostream> <br/> # include <queue> <br/> # include <Map> <br/> # include <vector> <br/> using namespace STD; <br/> # define N 8 // graph size </P> <p> int G [N] [N]; <br/> int godir [] [2] = {-}, {0,-1 }}; </P> <p> int gtoi (int A [] [N]) {<br/> int rs = 0; <br/> int loc = 10000000; <br/> for (INT I = 0; I <n; ++ I) {<br/> for (Int J = 0; j <n; ++ J) {<br /> If (a [I] [J] = 1) {<br/> Rs + = I * LOC; <br/> loc/= 10; <br/> Rs + = J * LOC; <br/> loc/= 10; <br/>}< br/> If (loc = 1) break; <br/>}< br/> If (loc = 1) break; <br/>}< br/> Return Rs; <br/>}</P> <p> void itog (int A [] [N], int st) {<br/> for (INT I = 0; I <n; ++ I) memset (A [I], 0, sizeof (A [I]); <br/> int loc = 10000000; <br/> int X, Y; <br/> for (INT I = 0; I <4; ++ I) {<br/> X = sT/loc % 10; <br/> loc/= 10; <br/> Y = ST /Loc % 10; <br/> loc/= 10; <br/> A [x] [Y] = 1; <br/>}</P> <p> void show (int A [] [N]) {<br/> for (INT I = 0; I <n; ++ I) {<br/> for (Int J = 0; j <n; ++ J) printf ("% d ", A [I] [J]); <br/> puts (""); <br/>}< br/> puts (""); <br/>}< br/> void show (INT Sta) {<br/> int a [n] [N]; <br/> itog (A, Sta ); <br/> show (a); <br/>}</P> <p> int findadj (vector <int> & adj, const int fr) {<br/> adj. clear (); <br/> int TMP [N] [N]; <br/> I NT ball [4] [2]; <br/> int loc = 10000000; <br/> for (INT I = 0; I <4; ++ I) {<br/> ball [I] [0] = fr/loc % 10; <br/> loc/= 10; <br/> ball [I] [1] = fr/loc % 10; <br/> loc/= 10; <br/>}< br/> for (INT I = 0; I <4; ++ I) {<br/> for (Int J = 0; j <4; ++ J) {<br/> itog (TMP, fr); <br/> int x = ball [I] [0] + godir [J] [0]; <br/> int y = ball [I] [1] + godir [J] [1]; <br/> int flag = 1; <br/> If (0 <= x & x <n & 0 <= Y & Y <n & TMP [x] [Y]! = 1) {<br/> flag = 0; <br/> TMP [x] [Y] = 1; <br/> TMP [Ball [I] [0] [Ball [I] [1] = 0; <br/> adj. push_back (gtoi (TMP); <br/>}< br/> If (FLAG) {<br/> X = ball [I] [0] + godir [J] [0] * 2; <br/> Y = ball [I] [1] + godir [J] [1] * 2; <br/> If (0 <= x & x <n & 0 <= Y & Y <n & TMP [x] [Y]! = 1) {<br/> TMP [x] [Y] = 1; <br/> TMP [Ball [I] [0] [Ball [I] [1] = 0; <br/> adj. push_back (gtoi (TMP )); <br/>}</P> <p> int dsbfs (int src, int des) {<br/> int dir = 0; // indicates the direction <br/> int e [2]; // target status <br/> queue <int> que [2]; // queue <br/>/* Dis is used to record the distance, because the status is only 8 ^ 8 = 16777216, but for convenience, <br/> it is saved with an 8-digit decimal integer, so there are 10 ^ 8 = 100000000 numbers, memory must overflow <br/> so use set to save the distance */<br/> Map <int, int> dis [2]; <br/> vect Or <int> adj; // search for FR extended nodes <br/> E [0] = des, E [1] = SRC; // e indicates the target to be searched by Dir. <br/> que [0]. push (SRC), que [1]. push (DES); <br/> dis [0] [SRC] = 1, DIS [1] [des] = 1; <br/>/* bidirectional wide search */<br/> while (! Que [0]. Empty () |! Que [1]. Empty () {<br/> dir = que [0]. Size () <= que [1]. Size ()? 0: 1; // search for Queues with fewer nodes for expansion <br/> If (que [dir]. Empty ()&&! Que [! Dir]. Empty () dir =! Dir; // If a queue is empty, find the remaining queue <br/> int Fr = que [dir]. front (); <br/> que [dir]. pop (); <br/> int frdis = dis [dir] [fr]; <br/> If (E [dir] = fr) {// found the other party <br/> return frdis; <br/>}< br/> If (DIS [! Dir] [fr]) {// you can find the extension state of the other party and return <br/> return dis [! Dir] [fr] + frdis-1; <br/>}< br/> findadj (adj, fr); <br/> for (INT I = 0; I <adj. size (); ++ I) {<br/> If (DIS [dir] [adj [I] = 0 & frdis + 1 <= 5) {// The status searched by the user will not be repeated and the distance is the shortest <br/> dis [dir] [adj [I] = frdis + 1; <br/> que [dir]. push (adj [I]); <br/>}< br/> return 0; <br/>}</P> <p> int main () {<br/> int X, Y; <br/> int SRC, des; <br/> while (scanf ("% d", & X)-EOF) {<br/> // enter the first graph <br/> scanf ("% d", & Y); <B R/> memset (G, 0, sizeof (g); <br/> G [x-1] [Y-1] = 1; <br/> for (INT I = 0; I <3; ++ I) {<br/> scanf ("% d", & X, & Y ); <br/> G [x-1] [Y-1] = 1; <br/>}< br/> src = gtoi (g); <br/> memset (G, 0, sizeof (g); <br/> // input of the second graph <br/> for (INT I = 0; I <4; ++ I) {<br/> scanf ("% d", & X, & Y); <br/> G [x-1] [Y-1] = 1; <br/>}< br/> des = gtoi (g); <br/> printf ("% s/n", dsbfs (SRC, des )? "Yes": "no"); <br/>}< br/> return 0; <br/>}

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.