SSL1092 magic board

SSL1092 magic board

Insert picture description here

algorithm

This question is obviously done with search, but it is easy to time out or even infinite loop when using deep search, which is not advisable. We can only do it with Guangsou. But the shortcomings of Guangsou are also obvious. There is no good way to judge whether the new state coincides with the old state. It is completely impossible to use a normal queue, so I thought of a hash table. So the algorithm for this question is determined, using Guangsou + Hash.

Ideas

Since it is a search, there must be a search direction. The three operations of ABC are given in the question, how should we implement it? It can be solved with a two-dimensional array of [3][8]. { {8,7,6,5,4,3,2,1},{4,1,2,3,6,7,8,5},{1,7,2,4,5,3, 6, 8}}, respectively represent the three operations of A, B, and C.
  Next is the design of the hash function. This is very simple, just use the remainder method. Mainly the choice of divisor. You must use prime numbers. There is a prime number that is particularly easy to remember, 31,331,3331,33331...all are prime numbers, except for 333333333331. For this question, take 333331 as the divisor.

Code

Send AC code~~

#include<iostream>
#include<cstdio>
#define p 333331
#define maxx 1000000
using namespace std;
string h[maxx],s,state[maxx];
int f[maxx],num[maxx],tail,head; 
int rule[3][8]={
    
    {
    
    8,7,6,5,4,3,2,1},{
    
    4,1,2,3,6,7,8,5},{
    
    1,7,2,4,5,3,6,8}};
char ls[maxx];
bool hash(string s){
    
    
	int ans=0;
	for(int i=0;i<8;i++){
    
    
		ans=ans*10+s[i]-'0';
	}
	int i=0;ans%=p;
	while(i<maxx && h[(i+ans)%p]!="" && h[(i+ans)%p]!=s){
    
    
		i++;
	}
	if(h[(i+ans)%p]==""){
    
    
		h[(i+ans)%p]=s;
		return false;
	}
	else{
    
    
		return true;
	}
}
void bfs(){
    
    
	hash("12345678");
	state[1]="12345678";
	head=0;tail=1;
	do{
    
    
		head++;
		for(int i=0;i<3;i++){
    
    
			tail++; 
			f[tail]=head; 
			state[tail]=""; 
			num[tail]=num[head]+1; 
			if (i==0) ls[tail]='A'; else
			if (i==1) ls[tail]='B'; else
			if (i==2) ls[tail]='C'; 
			for(int j=0;j<8;j++){
    
    
				state[tail]+=state[head][rule[i][j]-1];
			}	
			if(hash(state[tail])) tail--;
			else if(state[tail]==s) return;
			
		}
	}while(head<tail);
}
void print(int x){
    
    
	if(x==1){
    
    
		return;
	}
	print(f[x]);
	printf("%c",ls[x]);
}
int main(){
    
    
	int xx;
	for (int i=0;i<8;i++)
	 {
    
    scanf("%d",&xx);s+=xx+48; }
	if (s=="12345678"){
    
    
		printf("0");
		return 0;
	}
	bfs(); 
	printf("%d\n",num[tail]); 
	print(tail);
	return 0;
} 

Guess you like

Origin blog.csdn.net/weixin_54799322/article/details/112978795