題解P2730 [USACO3.2]魔板 Magic Squares
阿新 • • 發佈:2020-08-22
Link
P2730 [USACO3.2]魔板 Magic Squares
Solve
因為只有8個數的變換,我們直接強刷BFS就可以了,關鍵是如何判重複的問題,我們發現8的排列數其實不多,也就\(8!=40320\)所以可以記錄下來狀態,題解中有很多康託展開的方法非常好,而且效率也很高,說實話就是一種離散的方式,這裡給出康拓展開的轉移
\(X=a[n] \times (n-1)!+a[n-1] \times(n-2)!+...+a[i] \times(i-1)!+...+a[1] \times0!\)
其中\(a[i]\)為當前未出現的元素中是排在第幾個,也就是後面有幾個比我小的。這樣轉移的非常優秀。
但是我太懶
所以直接用一個map就給水殺過去了。
哈哈哈哈哈哈哈哈哈哈哈
Code
#include<cstdio> #include<iostream> #include<map> #include<cstring> #include<queue> using namespace std; string Ans; map<string,string> p; queue<string> Q; inline int read(){ int ret=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-f;ch=getchar();} while(ch<='9'&&ch>='0')ret=ret*10+ch-'0',ch=getchar(); return ret*f; } void A_(string lst){ string now=lst; for(int i=0;i<4;i++){ char ch=lst[i]; now[i]=lst[7-i]; now[7-i]=ch; } if(p.count(now)==0){ Q.push(now); p[now]=p[lst]+'A'; } return ; } void B_(string lst){ string now=lst; now[0]=lst[3];now[1]=lst[0];now[2]=lst[1];now[3]=lst[2];now[4]=lst[5];now[5]=lst[6];now[6]=lst[7];now[7]=lst[4]; if(p.count(now)==0){ Q.push(now); p[now]=p[lst]+'B'; } return ; } void C_(string lst){ string now=lst; now[1]=lst[6];now[2]=lst[1];now[5]=lst[2];now[6]=lst[5]; if(p.count(now)==0){ Q.push(now); p[now]=p[lst]+'C'; } return ; } void BFS(){ Q.push("12345678"); p["12345678"]=""; while(!Q.empty()){ A_(Q.front()); B_(Q.front()); C_(Q.front()); if(p.count(Ans)!=0){cout<<p[Ans].size()<<endl<<p[Ans]<<endl;return ;} Q.pop(); } return; } int main(){ freopen("P2730.in","r",stdin); freopen("P2730.out","w",stdout); for(int i=1;i<=8;i++){ int x=read(); Ans+=x+'0'; } BFS(); return 0; }