USACO msquare
使用康拓展开判重就行, 代码如下:
/* ID: m1500293 LANG: C++ PROG: msquare */ #include <cstdio> #include <cstring> #include <algorithm> #include <queue> #include <string> #include <iostream> using namespace std; int target[8]; struct State { int a[8]; int len; string op; State() {} State(int b[], int l, string s) { for(int i=0; i<8; i++) a[i] = b[i]; len = l; op = s; } }res; void opA(int a[]) { swap(a[0], a[7]); swap(a[1], a[6]); swap(a[2], a[5]); swap(a[3], a[4]); } void opB(int a[]) { int tp = a[3]; for(int i=3; i>=1; i--) a[i]=a[i-1]; a[0] = tp; tp = a[4]; for(int i=4; i<=6; i++) a[i]=a[i+1]; a[7] = tp; } void opC(int a[]) { int tp = a[1]; a[1] = a[6]; a[6] = a[5]; a[5] = a[2]; a[2] = tp; } int getnum(int a[]) { int res = 0; int fac[9]; fac[0] = 1; for(int i=1; i<9; i++) fac[i] = i*fac[i-1]; for(int i=0; i<8; i++) { int cnt = 0; for(int j=0; j<i; j++) if(a[j]>a[i]) cnt++; res += cnt*fac[i]; } return res; } bool vis[41000]; void bfs() { memset(vis, 0, sizeof(vis)); queue<State> que; int a[] = {1, 2, 3 ,4 ,5, 6, 7, 8}; vis[getnum(a)] = 1; que.push(State(a, 0, "")); while(!que.empty()) { State a = que.front(); que.pop(); if(memcmp(a.a, target, sizeof(target)) == 0) { res = a; return ; } int tp[8]; memcpy(tp, a.a, sizeof(tp)); opA(tp); if(!vis[getnum(tp)]) { vis[getnum(tp)] = 1; que.push(State(tp, a.len+1, a.op+"A")); } memcpy(tp, a.a, sizeof(tp)); opB(tp); if(!vis[getnum(tp)]) { vis[getnum(tp)] = 1; que.push(State(tp, a.len+1, a.op+"B")); } memcpy(tp, a.a, sizeof(tp)); opC(tp); if(!vis[getnum(tp)]) { vis[getnum(tp)] = 1; que.push(State(tp, a.len+1, a.op+"C")); } } } int main() { freopen("msquare.in", "r", stdin); freopen("msquare.out", "w", stdout); for(int i=0; i<8; i++) scanf("%d", &target[i]); bfs(); printf("%d\n", res.len); int output = 0; for(int i=0; i<res.len; i++) { cout<<res.op[i]; output++; if(output == 60) cout<<endl; } if(res.len%60 != 0 || res.len==0) cout<<endl; return 0; }