好的分層思想會使代碼簡單許多。
用了康拓展開,再次感覺到了數學的力量。
bfs的判定邊界條件的時候,一般可以分爲在得到新的狀態的時候判定是否重複,也可以在拿出來的時候判定。總體而言在得到的時候判定會減少一層判定樹的高度,但是要額外注意最開始的初始情況。
在TSOj中由於不能用stl中的數據,即必須自己手寫隊列,保存狀態等,但是可以用stl的時候用簡單了不少。
#include <stdio.h>
#include <string>
#include <string.h>
#include <iostream>
#include <queue>
using namespace std;
int const maxn = 100000;
int fact[8]={1,1,2,6,24,120,720,5040};
int g_n;
int g_ch[2][4];
int vis[maxn];
struct board {
int val;
int ch[2][4];
string operation;
int GetHash() {
int tmp[8],pt=0;
for (int i=0;i<2;i++)
for (int j=0;j<4;j++) {
tmp[pt++] = this->ch[i][j];
}
int gval=0;
for(int i=0;i<8;i++) {
int rank = 0;
for (int j=i+1;j<8;j++) {
if(tmp[i]>tmp[j]) rank++;
}
gval+=rank*fact[7-i];
}
this->val = gval;
return gval;
}
board operate(int i) {
board l_tmp;
switch (i) {
case 0:
for (int i=0;i<2;i++) {
for (int j=0;j<4;j++) {
l_tmp.ch[i][j] = this->ch[1-i][j];
}
}
l_tmp.GetHash();
l_tmp.operation = this->operation + "A";
return l_tmp;
case 1:
for(int i=0;i<2;i++) {
for (int j=0;j<4;j++) {
l_tmp.ch[i][(j+1)%4] = this->ch[i][j];
}
}
l_tmp.GetHash();
l_tmp.operation = this->operation + "B";
return l_tmp;
case 2:
for(int i=0;i<2;i++) {
for (int j=0;j<4;j++) {
l_tmp.ch[i][j] = this->ch[i][j];
}
}
l_tmp.ch[0][1] = this->ch[1][1];
l_tmp.ch[0][2] = this->ch[0][1];
l_tmp.ch[1][1] = this->ch[1][2];
l_tmp.ch[1][2] = this->ch[0][2];
l_tmp.GetHash();
l_tmp.operation = this->operation + "C";
return l_tmp;
}
}
};
bool match(board tmp) {
for (int i=0;i<2;i++) {
for (int j=0;j<4;j++) {
if(tmp.ch[i][j]!=g_ch[i][j]) return false;
}
}
return true;
}
void bfs() {
board tmp;
for (int i=0;i<4;i++) {
tmp.ch[0][i]=i+1;
tmp.ch[1][i]=8-i; }
tmp.operation = "";
tmp.GetHash();
memset(vis,0,sizeof(vis));
if(match(tmp)) {
cout<<0<<endl;
return;
}
queue<board> Q;
Q.push(tmp);
vis[tmp.val] = 1;
while(!Q.empty()) {
board l_var = Q.front();
Q.pop();
for (int i=0;i<3;i++) {
board l_tmp = l_var.operate(i);
if(l_tmp.operation.size()>g_n) {
cout<<-1<<"\n";
return ;
}
if(match(l_tmp)) {
cout<<l_tmp.operation.size()<<" "<<l_tmp.operation<<endl;
return ;
}
if(!vis[l_tmp.val]) {
vis[l_tmp.val]=1;
Q.push(l_tmp);
}
}
}
}
int main() {
// freopen("input.txt","r",stdin);
while(cin>>g_n&&g_n!=-1) {
for (int i=0;i<2;i++)
for (int j=0;j<4;j++) cin>>g_ch[i][j];
bfs();
}
return 0;
}