ZOJ 3814 Sawtooth Puzzle (2014 Mudanjiang Division network game f)

Source: Internet
Author: User

1. Title Description: Click to open the link

2. Problem-solving ideas: The subject is an implicit map of the search topic. In general, such topics define the state first, followed by figuring out how the state shifts, how the state is weighed, and how the current state is the same as the target State. As for solving the shortest circuit is commonly used BFS can. Let's start with a discussion.


1. the definition of the state : see this problem, a fierce will think of each character with 01, and then as a binary code for state compression, although this state definition can, but obviously, the state is too accurate and complex, if the line is compressed into an integer, then a complete pattern to use 8* 9, that is, 72 numbers can be described. is obviously too large, and the transfer of State has become extremely complex. So that's not a good definition. If we notice that the pattern of each block is rigid, it will be found that it is not what the pattern itself looks like, but how many times each pattern rotates relative to the initial state . That is, we only need to use 0~3 to accurately describe the number of times the block I is rotated relative to the initial state. In this way, we can describe a complete pattern with 9 integers that range in 0~3. What's more, we've found that there is a very big benefit to this definition: the rotation is very simple, and if it is rotated clockwise, it is 0->1,1->2,2->3,3->0, counterclockwise and vice versa. Therefore, this definition can be used as a good definition.


2. State transfer : According to test instructions description, we have to select a piece each time to rotate it clockwise, then, if the block and adjacent blocks have gear coupling between, then the adjacent block will also be driven rotation, and so on. That is, the rotation of a block may drive multiple blocks to rotate at the same time, which looks tricky. At this point we can consider using a constant array to handle. Because we entered at the time of the initial input of each block and left or right to have gears. Note, however, that this "upper-left-right" is for the initial state, so if we turn the block I to 90 degrees clockwise, then the new state "top left and right" is the original initial state of "lower left upper right". then rotate 90 degrees, it becomes the initial state of the "lower left top", and so on. That is, we can set a state transfer array to represent this situation. Using tp[i][j] means that when the state is I (I at this time the range is 0~3), its first J subscript corresponding to the initial gear array should be what the subscript (subscript starting from 1, note and the status of the range of values separated). According to the discussion just now, tp[0][1]=1,tp[0][2]=2,tp[0][3]=3,tp[0][4]=4;tp[1][1]=4,tp[1][2]=1,tp[1][3]=2,tp[1][4]=3.

After setting up this constant array, we can set up 4 constant arrays in order to get the number of the upper and lower left and right squares of block I in O (1) time. Use up[i],down[i],lef[i],rig[i] to indicate that the array is not difficult to write. With these 5 constant arrays, the Rotate function is very well written: first let the block I 90 degrees clockwise (that is, the corresponding value of +1), and then use a constant array to get it up and down the square number, Use the meshed function to determine if the 4 blocks (if they exist) have a gear coupling to the block I, or 1 for each. Next, for gear coupling, they are rotate operated, and vis[i] are used to mark whether they have been manipulated. In order to facilitate the expression of clockwise and counterclockwise, we use 1, and two. For example, block I rotates the number is flag, then adjacent to it becomes 3-flag. As for the meshed function, we can use the TP array to quickly obtain the corresponding gear subscript to determine if there is a coupling. This completes the state transition when the rotate is executed.


3. the state of the weight : We found that there are only 9 numbers, the range of changes in each number is 0~3, so you may wish to write a hash function, the 9 number is compressed into a unique integer. We found that 0~3 occupies 2 bits. Then you only need to translate a number of 2i bits at a time. If the subscript starts at 1, it is the i-1 bit (the first number does not move). You only need to pan 16 bits at most. Still within the INT range. And the resulting hash value must not be duplicated, can only represent a complete state. If we are using the D array (the distance array in BFS) to determine the weight, then first initialized to the INF, only need to see D[V] (V is the state corresponding to the hash value) is the INF to achieve the weight.


4. whether to reach the target State : Note that this step should not be confused with the state, because the objective state of the subject can actually be described with many pairs of state values, and can not be simple with the hash is the same to judge. For example, the 5th block in the title, no matter how it rotates, the pattern is the same. That is, the 5th State value is 0~3, which may be part of the target State. This suggests that we need to find a different way of judging. So how do you do it? Based on the definition of the state, we can first try to rotate each block 4 times (regardless of gear coupling) to see if the current state of rotation is exactly the same as the corresponding block pattern in the target State (that is, we need to use the input characters this time). The same thing, mark it as 1. If we use a COR array tag, then the cor[i][j]=1 indicates that the block I is rotated clockwise after J times and the Block I pattern of the target State. After this preprocessing, the judgment function is not difficult to write. Just look at all I, whether there is a cor[i][st[i]]=1 (St[i] Indicates the first state value component).


At this point, we successfully solved the 4 large implicit graph search problem, the remaining find the shortest is the ordinary BFS can be achieved, thus the perfect solution to the subject. The definition of state is the key to the problem. The set of constant arrays is also well worth learning.

3. Code:

#pragma COMMENT (linker, "/stack:1024000000,1024000000") #include <iostream> #include <algorithm># include<cassert> #include <string> #include <sstream> #include <set> #include <bitset># include<vector> #include <stack> #include <map> #include <queue> #include <deque># include<cstdlib> #include <cstdio> #include <cstring> #include <cmath> #include <ctime># Include<cctype> #include <functional>using namespace std; #define ME (s) memset (s,0,sizeof (s)) typedef long Long ll;typedef unsigned int uint;typedef unsigned long long ull;typedef pair <int, int> p;struct state{int st[1    1]; State () {} state (int a1,int a2,int a3,int a4,int a5,int a6,int a7,int a8,int A9) {st[1]=a1,st[2]=a2,st[3]=a3,    ST[4]=A4,ST[5]=A5,ST[6]=A6,ST[7]=A7,ST[8]=A8,ST[9]=A9; }};const int inf=100000000;const int up[]={0,0,0,0,1,2,3,4,5,6};const int down[]={0,4,5,6,7,8,9,0,0,0};const int lef[] ={0,0,1,2,0,4,5,0,7,8};const int rig[]={0,2,3,0,5,6,0,8,9,0};const int tp[4][5]={{0,1,2,3,4},{0,4,1,2,3},{0,3,4,1,2},{0,2,3,4,1}};queue< State>q;string s[10][10],t[10][10],p[10];int st[11][11];int vis[11];int cor[11][11];int d[1<<20];int ans; void Init_initial () {for (Int. i=0;i<3;i++) for (int j=1;j<=8;j++) cin>>s[i*3+1][j]>>s[i*3 +2][J]&GT;&GT;S[I*3+3][J];} void Init_target () {for (Int. i=0;i<3;i++) for (int j=1;j<=8;j++) cin>>t[i*3+1][j]>>t[i*3+ 2][J]&GT;&GT;T[I*3+3][J];}    int Hash (state x)//compress the status x {int res=0;    for (int i=1;i<=9;i++) res=res+ (x.st[i]<< (i-1)); return res;} BOOL Meshed (state x,int A,int e1,int b,int E2)//determine if the E1 orientation of the Block A and the E2 orientation of the B block have gears {int f1=st[a][tp[x.st[a]][e1]],f2=st[b][ TP[X.ST[B]][E2]];   Using the TP array to obtain the corresponding subscript return f1==1&&f2==1; quickly    are 1, indicating that there is a gear coupling}state rotate (state x,int y,int flag) {vis[y]=1;    int l=lef[y],r=rig[y],u=up[y],d=down[y];    BOOL fl=0,fu=0,fd=0,fr=0; if (L&&!viS[l]&&meshed (x,l,3,y,1)) fl=1;    if (r&&!vis[r]&&meshed (x,r,1,y,3)) fr=1;    if (u&&!vis[u]&&meshed (x,u,4,y,2)) fu=1;    if (d&&!vis[d]&&meshed (x,d,2,y,4)) fd=1;    int z=x.st[y];  if (flag==1) z= (z==3)? 0:z+1;    Rotate the y block clockwise 90 degrees else z= (z==0)? 3:z-1;    X.st[y]=z;        if (Fl&&!vis[l])//If there is a gear coupling on the left side of the Y block, and it has not been rotated, then the square on the left is rotated {vis[l]=1;    X=rotate (X,l,3-flag);        } if (Fr&&!vis[r]) {vis[r]=1;    X=rotate (X,r,3-flag);        } if (Fu&&!vis[u]) {vis[u]=1;    X=rotate (X,u,3-flag);        } if (Fd&&!vis[d]) {vis[d]=1;    X=rotate (X,d,3-flag); } return x;}    bool OK (state y) {for (int i=1;i<=9;i++) if (!cor[i][y.st[i]]) return 0; return 1;}    void BFs (state x) {while (!q.empty ()) Q.pop ();    Q.push (x);        while (!q.empty ()) {X=q.front (); Q.pop ();        int Sx=hash (x);   for (int i=1;i<=9;i++) {me (VIS);         State y=rotate (x,i,1);            int Sy=hash (y);                if (d[sy]>d[sx]+1) {d[sy]=d[sx]+1;                    if (ok (y)) {Ans=d[sy];                Return            } q.push (y); }}}}bool Same (int x)//using the COR array to achieve a judgment on the target State {for (int i=1;i<=8;i++) for (int j=0;j<8;j++) I    F (s[x][i][j]!=t[x][i][j]) return 0; return 1;}    void change (int x)  //rotates 90 degrees (regardless of gear coupling) on the X-squares (without regard to gearing) {for (int i=1;i<=8;i++) p[i]= "";    for (int. i=1;i<=8;i++) for (int j=8;j>=1;j--) p[i]=p[i]+s[x][j][i-1]; for (int i=1;i<=8;i++) s[x][i]=p[i];}    int main () {int T;    scanf ("%d", &t);  while (t--) {init_initial ();   Initializes the initial state of Init_target (); Initialize the target State for (int i=1;i<=9;i++) for (int j=1;j<=4;j++) scanf ("%d", &st[i][j]);   Gear Array Fill (d,d+ (1<<20), INF);   All distances are set to INF d[0]=0,ans=-1;     Me (COR); for (int i=1;i<=9;i++) for (int j=0;j<4;j++)//If the first J rotation of each square is equal to the target State for preprocessing {if (same (i)) cor I            [J]=1;        Change (i); } BFS (State (0,0,0,0,0,0,0,0,0));    Using BFS to find the shortest way printf ("%d\n", ans); }}


Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

ZOJ 3814 Sawtooth Puzzle (2014 Mudanjiang Division network game f)

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.