这道题显然是个宽搜(类似于8数码问题)。
只要每次按A、B、C三种方式进行宽度优先搜索,所以找到的第一次找到的解必定是步数最少的解。
另外,注意判重,(向用康托展开的dalao们膜拜),相比于康托展开(我这种菜蒟蒻听都没听过),我直接用c++的map<string,bool>来判重。
既不超空间,操作也很短~~(前提是,这里有大量字符串操作)
OK~下面附上AK代码:
#include<bits/stdc++.h>
using namespace std;
int front,rear,dep[5000005];
string how[5000005],zt[5000005],purpose;
map <string,bool> mp;
int main()
{
char ch;
for (int i = 1 ; i <= 4 ; i ++) cin>>ch , purpose += ch;
string tmp = "";
for (int i = 1 ; i <= 4 ; i ++) cin>>ch , tmp = ch + tmp;
purpose += tmp;
zt[1] = "12348765"; dep[1] = 0; how[1] = ""; mp[zt[1]] = 1;
front = 1 ; rear = 1;
while (front <= rear)
{
if (zt[front] == purpose)
{
cout<<dep[front]<<endl;
int cnt = 0;
for (int i = 0 ; i < how[front].length() ; i ++)
{
cnt ++;
if (cnt == 60) cout<<how[front][i]<<endl , cnt = 0; else cout<<how[front][i];
}
return 0;
}
//1:
string st = zt[front].substr(4,8) + zt[front].substr(0,4);
if (!mp[st])
{
mp[st] = 1;
rear ++;
zt[rear] = st;
dep[rear] = dep[front] + 1;
how[rear] = how[front] + 'A';
}
//2:
st = zt[front][3];
st = st + zt[front].substr(0,3);
st = st + zt[front][7] + zt[front][4] + zt[front][5] + zt[front][6];
if (!mp[st])
{
mp[st] = 1;
rear ++;
zt[rear] = st;
dep[rear] = dep[front] + 1;
how[rear] = how[front] + 'B';
}
//3:
st = zt[front];
st[1] = zt[front][5];
st[2] = zt[front][1];
st[6] = zt[front][2];
st[5] = zt[front][6];
if (!mp[st])
{
mp[st] = 1;
rear ++;
zt[rear] = st;
dep[rear] = dep[front] + 1;
how[rear] = how[front] + 'C';
}
front ++;
}
return 0;
}