题意:起初愣是没看出序列的意思,右边转盘的最后三个是在左边的转盘上,看了别人的后才发现,如果单纯的从头bfs是会超时的,而我们可以通过双向的bfs搜索就可以解决了,
#include <iostream>
#include <cstdio>
#include <cstring>
#include <map>
#include <queue>
using namespace std;
int t;
int judge;
char pu[30];
char start[30] = "034305650121078709:90121";
struct QUE
{
char status[30];
char step[30];
int stepnum;
}q,p;
map<string,string>vis; // 映射标记
map<string,int>viss;
queue<QUE>Q;
void zhuan(int way)
{
if (way == 1) // 左顺时针
{
char sb1 = q.status[10];
char sb2 = q.status[11];
for (int i = 11; i >= 2; i --)
q.status[i] = q.status[i - 2];
q.status[1] = sb2; q.status[0] = sb1;
q.status[23] = q.status[11];
q.status[22] = q.status[10];
q.status[21] = q.status[9];
}
if (way == 3) // 左逆时针
{
char sb1 = q.status[0];
char sb2 = q.status[1];
for (int i = 0; i < 10; i ++)
q.status[i] = q.status[i + 2];
q.status[11] = sb2; q.status[10] = sb1;
q.status[23] = q.status[11];
q.status[22] = q.status[10];
q.status[21] = q.status[9];
}
if (way == 4) // 右逆时针(并不是简单的直接旋转,反正就是要连21,22,23一起转)
{
char sb1 = q.status[22];
char sb2 = q.status[23];
for (int i = 23; i >= 12; i --)
q.status[i] = q.status[i - 2];
q.status[13] = sb2; q.status[12] = sb1;
q.status[11] = q.status[23];
q.status[10] = q.status[22];
q.status[9] = q.status[21];
}
if (way == 2) // 右顺时针
{
char sb1 = q.status[12];
char sb2 = q.status[13];
for (int i = 12; i < 22; i ++)
q.status[i] = q.status[i + 2];
q.status[23] = sb2; q.status[22] = sb1;
q.status[11] = q.status[23];
q.status[10] = q.status[22];
q.status[9] = q.status[21];
}
}
void bfs(char *a)
{
vis.clear();
while (!Q.empty())
Q.pop();
strcpy(q.status,a);
q.stepnum = 0;
q.step[0] = '\0';
vis[q.status] = "st";
Q.push(q);
while (!Q.empty())
{
p = Q.front();
Q.pop();
for (int i = 1; i <= 4; i++)
{
q = p;
zhuan(i);
if (vis[q.status] == "") // 空字符串作为没出现的标记
{
q.step[q.stepnum++] = i + '0';
q.step[q.stepnum] = '\0';
vis[q.status] = q.step;
Q.push(q);
}
}
if (p.stepnum == 8)
return;
}
}
void bfs2(char *a)
{
viss.clear();
while (!Q.empty())
Q.pop();
strcpy(q.status,a);
q.stepnum = 0;
q.step[0] = '\0';
viss[q.status] = 1;
Q.push(q);
while (!Q.empty())
{
p = Q.front();
if (vis[p.status] != "")
{
judge = 1;
return;
}
Q.pop();
for (int i = 1; i <=4; i++)
{
q = p;
zhuan(i);
if (viss[q.status] == 0)
{
q.step[q.stepnum++] = i + '0';
q.step[q.stepnum] = '\0';
viss[q.status] = 1;
Q.push(q);
}
}
if (p.stepnum == 9)
return;
}
}
int main()
{
scanf("%d%*c",&t);
while (t--)
{
int piece;
judge = 0;
for (int i = 0; i < 24; i++)
{
scanf("%d",&piece);
pu[i] = '0' + piece;
}
pu[24] = '\0';
if (strcmp(pu,start) == 0)
{
printf("PUZZLE ALREADY SOLVED\n");
continue;
}
bfs(start);
bfs2(pu);
if (judge)
{
printf("%s",p.step);
for (int i = vis[p.status].size() - 1; i >= 0; i--)
{
if (vis[p.status][i] == '1') printf("3");
if (vis[p.status][i] == '2') printf("4");
if (vis[p.status][i] == '3') printf("1");
if (vis[p.status][i] == '4') printf("2");
}
printf("\n");
}
else printf("NO SOLUTION WAS FOUND IN 16 STEPS\n");
}
return 0;
}