#include<cstdio>
#include<cstring>
#include<string>
#include<map>
#define MAXSTATE 10000000
using namespace std;
typedef int state[24];
state st[MAXSTATE],goal= {0 ,3 ,4, 3 ,0 ,5 ,6, 5, 0 ,1 ,2 ,1, 0, 7,8, 7, 0, 9 ,10, 9 ,0 ,1 ,2 ,1},temp;
int dist[MAXSTATE],back_father[MAXSTATE],father[MAXSTATE],back_path[MAXSTATE],path[MAXSTATE],ans;
map<string,int>vis;
map<string,int>back_vis;
void rotate(int *next, int *origin, int dir)
{
if(dir==1) // 左盘顺时针转
{
next[0] = origin[10], next[1] = origin[11];
memcpy(next+2, origin, sizeof(int)*10); // 大块的,连续数组元素的用memcpy节约时间
memcpy(next+12, origin+12, sizeof(int)*9);
next[21]=origin[7], next[22] = origin[8], next[23] = origin[9];
}
else if(dir==2) // 右盘顺时针转
{
memcpy(next+12, origin+14, sizeof(int)*10);
next[22] = origin[12], next[23] = origin[13];
memcpy(next, origin, sizeof(int)*9);
next[9] = next[21], next[10] = next[22], next[11] = next[23];
}
else if(dir==3) // 左盘逆时针转
{
memcpy(next, origin+2, sizeof(int)*10);
next[10] = origin[0], next[11] = origin[1];
memcpy(next+12, origin+12, sizeof(int)*9);
next[21]=next[9], next[22]=next[10], next[23]=next[11];
}
else if(dir==4) // 右盘逆时针转
{
next[12] = origin[22], next[13] = origin[23];
memcpy(next+14, origin+12, sizeof(int)*10);
memcpy(next, origin, sizeof(int)*9);
next[9] = next[21], next[10] = next[22], next[11] = next[23];
}
}
string change(state &s)
{
string str;
for(int i=0; i<24; i++)
str+=s[i]+'0';
return str;
}
void print_back()
{
string str=change(st[ans]);
int cur=back_vis[str];
while(cur)
{
printf("%d",back_path[cur]);
cur=back_father[cur];
}
}
void print_path(int cur)
{
if(cur)
{
print_path(father[cur]);
printf("%d",path[cur]);
}
}
int try_to_insert1(int s)
{
string str=change(st[s]);
if(!back_vis[str])
{
back_vis[str]=s;
return 1;
}
return 0;
}
int try_to_insert2(int s)
{
string str=change(st[s]);
if(!vis[str])
{
vis[str]=1;
return 1;
}
return 0;
}
//void change(state &tt,int d) ;
void change (state &,int);
bool frontbfs()
{
memset(father,0,sizeof(father));
vis.clear();
vis[change(temp)]=1;
int front=0,rear=1;
memcpy(st[0],temp,sizeof(temp));
while(front<rear)
{
state &s=st[front];
if(dist[front]>8)
{
++front;
continue;
}
if(memcmp(goal,s,sizeof(s))==0)
{
ans=front;
return false;
}
if(back_vis[change(s)])
{
ans=front;
return true;
}
for(int d=1; d<=4; d++)
{
state &tt=st[rear];
memcpy(tt,s,sizeof(s));
//change (tt,d);
rotate(tt, s, d);
dist[rear]=dist[front]+1;
if(try_to_insert2(rear))
{
father[rear]=front;
path[rear]=d;
rear++;
}
}
front++;
}
ans=-1;
return ans;
}
bool backbfs()
{
memset(back_father,0,sizeof(back_father));
dist[0]=dist[1]=0;
back_vis.clear();
back_vis[change(goal)]=1;
int front=0,rear=1;
memcpy(st[0],goal,sizeof(goal));
while(front<rear)
{
state &s=st[front];
if(dist[front]>8)
{
++front;
continue;
}
for(int d=1; d<=4; d++)
{
state &tt=st[rear];
memcpy(tt,s,sizeof(s));
//change (tt,d);
rotate(tt, s, d);
dist[rear]=dist[front]+1;
if(try_to_insert1(rear))
{
back_father[rear]=front;
if(d==1) back_path[rear]=3;
else if(d==2) back_path[rear]=4;
else if(d==3) back_path[rear]=1;
else if(d==4) back_path[rear]=2;
rear++;
}
}
front++;
}
return false;
}
int main()
{
//freopen("in.txt","r",stdin);
int cas;
backbfs();
scanf("%d",&cas);
while(cas--)
{
for(int i=0; i<24; i++)
scanf("%d",&temp[i]);
if(memcmp(goal,temp,sizeof(temp))==0)
{
printf("PUZZLE ALREADY SOLVED\n");
continue;
}
frontbfs();
if(ans==-1)
{
printf("NO SOLUTION WAS FOUND IN 16 STEPS\n");
continue;
}
print_path(ans);
print_back();
printf("\n");
}
return 0;
}
uva 704 - Colour Hash
最新推荐文章于 2016-12-28 22:12:22 发布