Magic Squares
IOI ' 96
Following the success of the Magic Cube, Mr Rubik invented its planar version, called Magic Squares. This is a sheet composed of 8 equal-sized squares:
In this task we consider the version where each square has a different color. Colors is denoted by the first 8 positive integers. A sheet configuration is given by the sequence of colors obtained by reading the colors of the squares starting at the UPP Er left corner and going in clockwise direction. For instance, the configuration of Figure 3 was given by the sequence (1,2,3,4,5,6,7,8). This configuration is the initial configuration.
Three basic transformations, identified by the letters ' A ', ' B ' and ' C ', can is applied to A sheet:
- ' A ': Exchange the top and bottom row,
- ' B ': single right circular shifting of the rectangle,
- ' C ': Single clockwise rotation of the middle four squares.
Below is a demonstration of applying the transformations to the initial squares given above:
All possible configurations is available using the three basic transformations.
You is to write a program this computes a minimal sequence of basic transformations that transforms the initial Configura tion above to a specific target configuration.
Program Name:msquareinput FORMAT
A eight space-separated integers (a permutation of (1..8)) that is the target configuration.
SAMPLE INPUT (file msquare.in)
OUTPUT FORMAT
| Line 1: |
A single integer which is the length of the shortest transformation sequence. |
| Line 2: |
The lexically earliest string of transformations expressed as a string of characters, per line except possibly the last Line. |
SAMPLE OUTPUT (file msquare.out)
7BCABCCB
Test Instructions: A template has three operations: A, B, c,a operation when the next two lines of exchange, B operation when the last column is inserted in the front, C operation will be the middle four clockwise rotation. Tells you the initial state and the target State, the minimum number of times the operation can change to the target State, and output its sequence of operations. Enter the target state when you enter it clockwise.
Idea:
is BFS. The
is used to determine the direct violence of the map under the sentence. Another way is that Cantor expands to get a hash value.
to see if this value has occurred is OK. The
use of Cantor expands not only to reduce the space to n! (n is the string length, here is 8) and also soon.
Recommended ~
for Cantor expansion:
x=a[n]* (n-1)!+a[n-1]* (n-2)!+...+a[i]* (i-1)!+...+a[1]*0! (where A[i] For elements that do not currently appear in the first (starting from 0)) (the Web is very complex)
(in fact, the number of small && not appear in the current position of the number of a total of how many) (the essence is in the full arrangement than the current arrangement of the total number of a few). This is Cantor unfolding. (The hash value of +1 is the ordinal number of this arrangement itself (is the first few) (starting from 1))
Contor code:
const int FRAC[msquare_size]= {1, 1, 2, 6, all,, 720, 5040};//This array holds each of the above classes
The default string length here is 8.
InlineintContor (String &v) { intAns =0; for(inti =0; I <8; i++) { intTMP =0; for(intj = i+1; J <8; J + +)if(V[i] > V[j]) + +tmp
Count the number of small && not seen in the current position.
Of course, it's equal to the number of smaller numbers behind the current position than the current position.
Ans+ = tmp * frac[7-i]; } returnans+1;}
The following is the topic code:
/*Id:andy Chenlang:c++prog:msquare*/#include<iostream>#include<cstdio>#include<queue>#include<string>#include<map>#defineMAXN 10000using namespacestd;structstate{stringS,ans; intstep;};CharAns[maxn];map<string,BOOL>Vis;stringtail;stringOpA (stringa) { inti; for(i=0;i<4; i++) Swap (a[i],a[i+4]); returnA;}stringOpB (stringa) { CharT; T=a[3];a[3]=a[2];a[2]=a[1];a[1]=a[0];a[0]=T; T=a[7];a[7]=a[6];a[6]=a[5];a[5]=a[4];a[4]=T; returnA;}stringOpC (stringa) { CharT; T=a[1];a[1]=a[5];a[5]=a[6];a[6]=a[2];a[2]=T; returnA;}voidBFS () {BOOLFlag; State T,tt; T.step=0; t.s="12348765"; t.ans=""; Queue<state>p; Q.push (t); VIS[T.S]=true; while(! Q.empty ())//The following vis can be replaced with the hash value of Cantor expansion. Judging{T=Q.front (); Q.pop (); if(t.s==tail) {cout<<t.step<<endl<<t.ans<<Endl; return ; } Tt.ans=T.ans; Tt.step=t.step+1; Flag=false; Tt.s=OpA (T.S); if(!Vis[tt.s]) {Vis[tt.s]=true; Tt.ans+='A'; Q.push (TT); Flag=true; } Tt.s=OpB (T.S); if(!Vis[tt.s]) {Vis[tt.s]=true; if(!flag) tt.ans+='B'; Elsett.ans[t.step]='B'; Q.push (TT); Flag=true; } Tt.s=OpC (T.S); if(!Vis[tt.s]) {Vis[tt.s]=true; if(!flag) tt.ans+='C'; Elsett.ans[t.step]='C'; Q.push (TT); } }}intMain () {Freopen ("msquare.in","R", stdin); Freopen ("Msquare.out","W", stdout); inti; stringT; for(i=1; i<=8; i++) {cin>>t;tail+=T; } Swap (tail[4],tail[7]); Swap (tail[5],tail[6]);//because it is entered clockwise, you need to manually swap the position. BFS (); return 0;}
Feed Ratios (Cantor expand)