大概思路跟1150的一样,数据量大了,我刚开始是用set<string>来存已经变换过的魔板,结果TLE,后来网上查了一下,用康托,结果WA。。但是我又不知道错在哪。最后用set<int>来存,AC了哦
已换康托,0.22sec,不错。
void setFac() {
fac[0] = 1;
for(int i = 2; i <= 7; i++) {
fac[i - 1] = fac[i - 2] * i;
}
}
int getID(int *data) {
bool used[8];
memset(used, false, sizeof(used));
int id = 0;
for(int i = 0; i < 8; i++) {
for(int j = 1; j < data[i]; j++) {
if(!used[j - 1])
id += fac[6 - i];
}
used[data[i] - 1] = true;
}
return id;
}
void bfs() {
memset(isUsed, false, sizeof(isUsed));
queue<node> q;
node _front;
memcpy(_front.s, init, sizeof(init));
_front.step = "";
isUsed[getID(init)] = true;
node _tmp;
q.push(_front);
int id;
while(!q.empty()) {
_front = q.front();
q.pop();
int step = _front.step.size();
if(memcmp(_front.s, tar, sizeof(tar)) == 0) {
cout << step << " "
<< _front.step << endl;
return ;
}
if(step >= maxStep) continue;
_tmp = _front;
//A operator
_tmp.s[0] = _front.s[4];
_tmp.s[1] = _front.s[5];
_tmp.s[2] = _front.s[6];
_tmp.s[3] = _front.s[7];
_tmp.s[4] = _front.s[0];
_tmp.s[5] = _front.s[1];
_tmp.s[6] = _front.s[2];
_tmp.s[7] = _front.s[3];
id = getID(_tmp.s);
if(!isUsed[id]) {
_tmp.step = _front.step + "A";
q.push(_tmp);
isUsed[id] = true;
}
//B operator
_tmp.s[0] = _front.s[3];
_tmp.s[1] = _front.s[0];
_tmp.s[2] = _front.s[1];
_tmp.s[3] = _front.s[2];
_tmp.s[4] = _front.s[7];
_tmp.s[5] = _front.s[4];
_tmp.s[6] = _front.s[5];
_tmp.s[7] = _front.s[6];
id = getID(_tmp.s);
if(!isUsed[id]) {
_tmp.step = _front.step + "B";
q.push(_tmp);
isUsed[id] = true;
}
//C operator
_tmp.s[0] = _front.s[0];
_tmp.s[1] = _front.s[5];
_tmp.s[2] = _front.s[1];
_tmp.s[3] = _front.s[3];
_tmp.s[4] = _front.s[4];
_tmp.s[5] = _front.s[6];
_tmp.s[6] = _front.s[2];
_tmp.s[7] = _front.s[7];
id = getID(_tmp.s);
if(!isUsed[id]) {
_tmp.step = _front.step + "C";
q.push(_tmp);
isUsed[id] = true;
}
}
cout << -1 << endl;
}
int main() {
int a;
setFac();
while(cin >> maxStep && maxStep != -1) {
for(int i = 0; i < 8; i++) {
cin >> tar[i];
}
bfs();
}
return 0;
}