[BFS] Magic Board (c++ basic algorithm)

  

Previous article in this column: [BFS] Eight-digit problem (c++ basic algorithm)


Table of contents

1. Reading questions

①Question

 ②Question meaning

3. Do the questions

①Algorithm principle

② Algorithm implementation

ⅠThree basic operations

ⅡOperation sequence

ⅢOutput

ⅣA special situation

4.AC code

at last


1. Reading questions

①Question

[Kuansou (Difficulty: 6)] Magic Board

[Problem Description]
After successfully inventing the Rubik's Cube, Mr. Rubik invented its two-dimensional version, called the Magic Board.
This is a magic board with 8 grids of the same size:
Uploading...Reupload Cancel
We know that each square on the magic board has a color. These 8 colors are represented by the first 8 positive integers. A sequence of colors can be used to represent a magic board state. It is stipulated that starting from the upper left corner of the magic board, integers are taken out in a clockwise direction to form a color sequence.
For the magic board state in the picture above, we use the sequence (1, 2, 3, 4, 5, 6, 7, 8) to represent it. This is the basic state.
There are three basic operations provided here, represented by capital letters "A", "B", and "C" respectively (the status of the magic board can be changed through these operations):
"A": Swap the upper and lower lines;
"B": Change The rightmost column is inserted into the leftmost column;
"C": The four squares in the center of the magic board are rotated clockwise.
The following is a demonstration of operations on the basic states:
A:
8 7 6 5
1 2 3 4
B:
4 1 2 3 5
8 7 6
C:
1 7 2 4
8 6 3 5
For each possible state, these three Basic operations are available.
You need to program and calculate the conversion from the basic state to the target state with the least basic operations, and output the basic operation sequence.
[Input format]
There is only one line, including 8 integers, separated by spaces (these integers are in the range 1-8), indicating the target state.
[Output format]
The first line includes an integer, indicating the length of the shortest operation sequence.
The operation sequence that appears earliest in the second line in lexicographic order is represented by a string. Except for the last line, each line outputs 60 characters.
[Sample input]
2 6 8 4 5 7 3 1
[Sample output]
7
BCABCCB

 ②Question meaning

Obviously, this question asks us to find the number of steps and change operations for 12345678 to reach the target state after three changes.


3. Do the questions

①Algorithm principle

This question is very similar to the [BFS] eight-digit question . I will tell you this question while discussing the differences between the two.

② Algorithm implementation

ⅠThree basic operations

Compared to the up, down, left, and right operations of the eight-digit space, this question has three different operations.

"A": Swap the upper and lower rows;
"B": Insert the rightmost column into the leftmost column;
"C": Rotate the four squares in the center of the magic board clockwise.
The following is an example of operating on the basic states:
A:
8 7 6 5
1 2 3 4
B:
4 1 2 3 5
8 7 6
C:
1 7 2 4
8 6 3 5

I see many people using two-dimensional arrays to do it, but I don't think it is necessary. I do it directly in the main function using the switch() statement.

"A" function: loop j from 1-4, swap a[j] with a[9-j].

"B" function: loop j from 1-3, exchange a[j], a[4], and a[9-j], a[5]. (Continuously add 1 to the jth column [j will continue to add 1] and The last column is exchanged and the goal is finally achieved)

"C" function, just swap it out.

switch(i)
			{
				case 1:
					for(int i=1;i<=4;i++)
					{
						swap(ne.a[i],ne.a[9-i]);
					}
					break;
				case 2: 
					for(int i=1;i<=3;i++)
					{
						swap(ne.a[i],ne.a[4]);
						swap(ne.a[9-i],ne.a[5]);
					}
					break;
				case 3: 
					swap(ne.a[3],ne.a[6]);
					swap(ne.a[7],ne.a[3]);
					swap(ne.a[3],ne.a[2]);
			}

ⅡOperation sequence

I assign each situation a sequence. When this situation is feasible (it has not happened before), first assign the previous sequence to it, and then add the sequence of this operation.

	for(int k=1;k<=q.front().ans;k++) ne.bz[k]=q.front().bz[k];
	ne.bz[ne.ans]=i;

ⅢOutput

First output the number of operations, then operate on the sequence, and then output.

Operation on the sequence: On the original basis, force conversion to character, add 'A', and subtract one (because when the sequence number is 1, A should be output, and it is not recommended to become B, so subtract one)

	if(ne.kt==ed.kt)
   {
       printf("%d\n",q.back().ans);
       for(int k=1;k<=q.back().ans;k++) printf("%c",q.back().bz[k]+'A'-1);
       exit(0); 
    }

ⅣA special situation

When the target state is the same as the initial state, I will not be able to enter my output statement. Therefore, a 0 should be output at the end (because when the above situation occurs, no operation is needed to reach the target state)


4.AC code

No more comments!

#include<bits/stdc++.h>
using namespace std;
struct node{
	int kt,ans,bz[1005];
	int a[10];
}st,ed;
bool b[50000];
queue<node>q;
long kt(node t)
{
	long long s=1;
	for(int i=1;i<=8;i++)
	{
		int index=1,f=1,count=0;
		for(int j=i+1;j<=8;j++)
		{
			if(t.a[i]>t.a[j]) count++;
			f*=index++;
		}
		s=s+f*count;
	}
	return s;
}
int main()
{
	for(int i=1;i<=8;i++) st.a[i]=i;
	
	st.kt=kt(st);
	b[st.kt]=1;
	for(int i=1;i<=8;i++) scanf("%d",&ed.a[i]);
	ed.kt=kt(ed);
	q.push(st);
	while(!q.empty())
	{
		for(int i=1;i<=3;i++)
		{
			node ne=q.front();
			switch(i)
			{
				case 1:
					for(int i=1;i<=4;i++)
					{
						swap(ne.a[i],ne.a[9-i]);
					}
					break;
				case 2: 
					for(int i=1;i<=3;i++)
					{
						swap(ne.a[i],ne.a[4]);
						swap(ne.a[9-i],ne.a[5]);
					}
					break;
				case 3: 
					swap(ne.a[3],ne.a[6]);
					swap(ne.a[7],ne.a[3]);
					swap(ne.a[3],ne.a[2]);
			}
			ne.ans++;
			ne.kt=kt(ne);
			if(!b[ne.kt])
			{
				
				for(int k=1;k<=q.front().ans;k++) ne.bz[k]=q.front().bz[k];
				ne.bz[ne.ans]=i;
				b[ne.kt]=1;
				q.push(ne); 
				if(ne.kt==ed.kt)
                {
                	printf("%d\n",q.back().ans);
                	for(int k=1;k<=q.back().ans;k++) printf("%c",q.back().bz[k]+'A'-1);
                	exit(0); 
            }
			}
		}
		q.pop();
	}
	printf("0"); 
} 

at last

I started writing while taking online classes, and it was very hard. It's not too much to give a red heart. . .

Guess you like

Origin blog.csdn.net/aliyonghang/article/details/128439955