【BFS】 hihocoder 1233 Boxes
题意:给n(n < 8)个不同大小的盒子,小盒子可以叠在大盒子上,每次可向左或右相邻的位置移动,求使所有盒子从小到大有序所需最少移动次数
思路:v[n][n][n]...[n]表示第i大的数在那个位置,然后从最终状态暴力搜出所有状态即可。
代码:
#include <cstdio> #include <queue> #include <algorithm> #include <cstring> using namespace std; int v7[8][8][8][8][8][8][8]; int v6[8][8][8][8][8][8]; int v5[8][8][8][8][8]; int v4[8][8][8][8]; int v3[8][8][8]; int v2[8][8]; bool check(int a[],int n,int step){ if(n==2){ if(v2[a[1]][a[2]]!=-1) return 0; else { v2[a[1]][a[2]]=step;return 1; } } else if(n==3){ if(v3[a[1]][a[2]][a[3]]!=-1) return 0; else { v3[a[1]][a[2]][a[3]]=step;return 1; } } else if(n==4){ if(v4[a[1]][a[2]][a[3]][a[4]]!=-1) return 0; else { v4[a[1]][a[2]][a[3]][a[4]]=step;return 1; } } else if(n==5){ if(v5[a[1]][a[2]][a[3]][a[4]][a[5]]!=-1) return 0; else { v5[a[1]][a[2]][a[3]][a[4]][a[5]]=step;return 1; } } else if(n==6){ if(v6[a[1]][a[2]][a[3]][a[4]][a[5]][a[6]]!=-1) return 0; else { v6[a[1]][a[2]][a[3]][a[4]][a[5]][a[6]]=step;return 1; } } else if(n==7){ if(v7[a[1]][a[2]][a[3]][a[4]][a[5]][a[6]][a[7]]!=-1) return 0; else { v7[a[1]][a[2]][a[3]][a[4]][a[5]][a[6]][a[7]]=step;return 1; } } } struct node{ int a[10]; int step; }; void solve(int n){ int a[10]; for(int i=1;i<=n;i++) a[i]=i; check(a,n,0); queue<node> qq; node s;s.step=0; for(int i=1;i<=n;i++) s.a[i]=i; qq.push(s); while(!qq.empty()){ s=qq.front();qq.pop(); for(int i=1;i<=n;i++){//第i个点向左或右移 int l=1, r=1; for(int j=1;j<i;j++){ if(s.a[j]==s.a[i]-1) l=0;//左有更小的 if(s.a[j]==s.a[i]+1) r=0;//右有更小的 if(s.a[j]==s.a[i]) l=r=0;//该点上方有更小的 } if(s.a[i]-1<1) l=0; if(s.a[i]+1>n) r=0; if(l){ s.a[i]=s.a[i]-1;s.step+=1; if(check(s.a,n,s.step)) qq.push(s); s.a[i]+=1;s.step-=1; } if(r){ s.a[i]+=1;s.step+=1; if(check(s.a,n,s.step)) qq.push(s); s.a[i]-=1;s.step-=1; } } } } void init(){ memset(v7,-1,sizeof(v7)); memset(v6,-1,sizeof(v6)); memset(v5,-1,sizeof(v5)); memset(v4,-1,sizeof(v4)); memset(v3,-1,sizeof(v3)); memset(v2,-1,sizeof(v2)); for(int i=2;i<=7;i++){ solve(i); } } int h[10005],a[10],b[10]; int main() { int T; scanf("%d", &T); init(); while(T--){ int n; scanf("%d", &n); for(int i=1;i<=n;i++){ scanf("%d", &b[i]);h[b[i]]=i; } sort(b+1,b+1+n); for(int i=1;i<=n;i++) a[i]=h[b[i]]; if(n==1) printf("0\n"); else if(n==2) printf("%d\n",v2[a[1]][a[2]]); else if(n==3) printf("%d\n",v3[a[1]][a[2]][a[3]]); else if(n==4) printf("%d\n",v4[a[1]][a[2]][a[3]][a[4]]); else if(n==5) printf("%d\n",v5[a[1]][a[2]][a[3]][a[4]][a[5]]); else if(n==6) printf("%d\n",v6[a[1]][a[2]][a[3]][a[4]][a[5]][a[6]]); else if(n==7) printf("%d\n",v7[a[1]][a[2]][a[3]][a[4]][a[5]][a[6]][a[7]]); } return 0; }