要求:4*8的表格里面有4*7个牌,牌是两位数,十位数不超过4 ,个位数不超过7,第一列刚开始是没有牌,然后把个位数为1的牌放在第1列,其中十位数为i的放在第i排,原来个位数为1的牌的地方留下4个空格。然后开始移动牌,若一个牌为i*10+j,j<7,且右边有空格,则可将数字为i*10+j+1的牌放在该牌右边的空格内。问是否可以移动成下图,若可以,求出最小步数。
方法:bfs+hash
1.4个空格的填入方法相当于常规bfs题的四个方向移动。
2.若一个空格的左边还是空格,则该空格不能填牌。
3.标记状态用hash,空格相当于0,将32个数字按顺序组成一个大数,然后模999992,模这个数不知道对不对,但模数可以判重。
#include<iostream>
#include<stdio.h>
#include<queue>
#include<map>
#include<string.h>
#include<math.h>
#include<algorithm>
#define inf 0x3f3f3f3f
using namespace std ;
struct node
{
int map1[4][8] ;
int step ;
int x1 , y1 ;
int x2 , y2 ;
int x3 , y3 ;
int x4 , y4 ;
} ;
queue <node> q ;
int get_hash(node a)
{
int i , j ;
int ans = 0 ;
for(i = 0 ; i < 4 ; i ++)
for(j = 0 ; j < 8 ; j ++)
ans = (ans * 10 + a.map1[i][j]) % 999992 ;
return ans ;
}
void bfs()
{
int i , j , k , t , p ;
int hash ;
node a , b ;
map <int , bool> vis ;
while(!q.empty())
{
a = q.front() ;
//printf("%d\n" , a.step) ;
q.pop() ;
int flag = 1 ;
for(i = 0 ; i < 4 ; i ++)
for(j = 0 ; j < 7 ; j ++)
if(a.map1[i][j] != (i + 1) * 10 + (j + 1))
flag = 0 ;
if(flag)
{
printf("%d\n" , a.step) ;
return ;
}
for(i = 1 ; i <= 4 ; i ++)
{
if(i == 1)
{
if(a.map1[a.x1][a.y1-1] == 0 || a.map1[a.x1][a.y1-1] % 10 == 7)
continue ;
for(j = 0 ; j < 4 ; j ++)
for(k = 1 ; k < 8 ; k ++)
if(a.map1[j][k] - a.map1[a.x1][a.y1 - 1] == 1)
{
memcpy(b.map1 , a.map1 , sizeof(a.map1)) ;
b.map1[a.x1][a.y1] = a.map1[j][k] ;
b.map1[j][k] = 0 ;
b.x1 = j , b.y1 = k ;
b.x2 = a.x2 , b.y2 = a.y2 ;
b.x3 = a.x3 , b.y3 = a.y3 ;
b.x4 = a.x4 , b.y4 = a.y4 ;
b.step = a.step + 1 ;
hash = get_hash(b) ;
if(!vis[hash])
{
vis[hash] = 1 ;
q.push(b) ;
}
}
}
else if(i == 2)
{
if(a.map1[a.x2][a.y2-1] == 0 || a.map1[a.x2][a.y2-1] % 10 == 7)
continue ;
for(j = 0 ; j < 4 ; j ++)
for(k = 1 ; k < 8 ; k ++)
if(a.map1[j][k] - a.map1[a.x2][a.y2 - 1] == 1)
{
memcpy(b.map1 , a.map1 , sizeof(a.map1)) ;
b.map1[a.x2][a.y2] = a.map1[j][k] ;
b.map1[j][k] = 0 ;
b.x1 = a.x1 , b.y1 = a.y1 ;
b.x2 = j , b.y2 = k ;
b.x3 = a.x3 , b.y3 = a.y3 ;
b.x4 = a.x4 , b.y4 = a.y4 ;
b.step = a.step + 1 ;
hash = get_hash(b) ;
if(!vis[hash])
{
vis[hash] = 1 ;
q.push(b) ;
}
}
}
else if(i == 3)
{
if(a.map1[a.x3][a.y3-1] == 0 || a.map1[a.x3][a.y3-1] % 10 == 7)
continue ;
for(j = 0 ; j < 4 ; j ++)
for(k = 1 ; k < 8 ; k ++)
if(a.map1[j][k] - a.map1[a.x3][a.y3 - 1] == 1)
{
memcpy(b.map1 , a.map1 , sizeof(a.map1)) ;
b.map1[a.x3][a.y3] = a.map1[j][k] ;
b.map1[j][k] = 0 ;
b.x1 = a.x1 , b.y1 = a.y1 ;
b.x2 = a.x2 , b.y2 = a.y2 ;
b.x3 = j , b.y3 = k ;
b.x4 = a.x4 , b.y4 = a.y4 ;
b.step = a.step + 1 ;
hash = get_hash(b) ;
if(!vis[hash])
{
vis[hash] = 1 ;
q.push(b) ;
}
}
}
else
{
if(a.map1[a.x4][a.y4-1] == 0 || a.map1[a.x4][a.y4-1] % 10 == 7)
continue ;
for(j = 0 ; j < 4 ; j ++)
for(k = 1 ; k < 8 ; k ++)
if(a.map1[j][k] - a.map1[a.x4][a.y4 - 1] == 1)
{
memcpy(b.map1 , a.map1 , sizeof(a.map1)) ;
b.map1[a.x4][a.y4] = a.map1[j][k] ;
b.map1[j][k] = 0 ;
b.x1 = a.x1 , b.y1 = a.y1 ;
b.x2 = a.x2 , b.y2 = a.y2 ;
b.x3 = a.x3 , b.y3 = a.y3 ;
b.x4 = j , b.y4 = k ;
b.step = a.step + 1 ;
hash = get_hash(b) ;
if(!vis[hash])
{
vis[hash] = 1 ;
q.push(b) ;
}
}
}
}
}
/*for(i = 0 ; i < 4 ; i ++)
{
for(j = 0 ; j < 8 ; j ++)
printf("%d " , a.map1[i][j]) ;
printf("\n") ;
}*/
printf("-1\n") ;
}
int main()
{
int i , j ;
int t ;
node a ;
scanf("%d" , &t) ;
while(t--)
{
for(i = 0 ; i < 4 ; i ++)
for(j = 1 ; j < 8 ; j ++)
{
scanf("%d" , &a.map1[i][j]) ;
if(a.map1[i][j] == 11)
{
a.map1[i][j] = 0 ;
a.map1[0][0] = 11 ;
a.x1 = i ;
a.y1 = j ;
}
else if(a.map1[i][j] == 21)
{
a.map1[i][j] = 0 ;
a.map1[1][0] = 21 ;
a.x2 = i ;
a.y2 = j ;
}
else if(a.map1[i][j] == 31)
{
a.map1[i][j] = 0 ;
a.map1[2][0] = 31 ;
a.x3 = i ;
a.y3 = j ;
}
else if(a.map1[i][j] == 41)
{
a.map1[i][j] = 0 ;
a.map1[3][0] = 41 ;
a.x4 = i ;
a.y4 = j ;
}
}
a.step = 0 ;
while(!q.empty())
q.pop() ;
q.push(a) ;
bfs() ;
}
}