【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;
}
View Code

 

posted @ 2015-09-21 21:33  mithrilhan  阅读(170)  评论(0编辑  收藏  举报