山东省第七届省赛L题

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
typedef long long ll;
#define rep(i , n) for(int i = 0 ; i < (int)n ; i++)
#define rep1(i , x, y) for(int i = (int)x; i<=(int)y; i++)

const int inf = 0x3f3f3f3f;
int encode(int* a){
    int num = 0 ;
    rep(i, 6)
    num = num * 10 + a[i];
    return num;
}
void decode(int x,int * a){
    for(int i = 5 ; i>= 0 ; i--)
    {
        a[i] = x % 10;
        x/=10;
    }
}
const int N = 1e6 + 100;
int vis[N][6][6], VIS[N][6];
struct node
{
    int s, p, max_;
    node(int s = 0,int p = 0, int max_ = 0) :s(s),p(p), max_(max_) {}
};
queue<node> q;
void Push(int s, int p, int max_,int val){
    if(vis[s][p][max_] == -1)
    {
        vis[s][p][max_] =  val + 1;
        VIS[s][max_] = min(vis[s][p][max_], VIS[s][max_]);
        q.push(node(s, p ,max_));
    }
}
void init_bfs(){
    memset(vis,-1,sizeof(vis));
    memset(VIS,inf,sizeof(VIS));
    VIS[123456][0] = 0;
    int a[7];
    rep(i, 6) a[i] = i + 1;
    q.push(node(encode(a), 0, 0));
    vis[encode(a)][0][0] = 0;
    while(!q.empty())
    {
        node u = q.front();
        q.pop();
        int val = vis[u.s][u.p][u.max_];
        if(u.p > 0)
        {
            Push(u.s, u.p - 1, u.max_, val);
            int b[7];
            decode(u.s, b);
            swap(b[u.p], b[u.p - 1]);
            int nts = encode(b);
            Push(nts, u.p, u.max_, val);
        }
        if(u.p < 5)
        {
            Push(u.s, u.p + 1, max(u.max_, u.p + 1), val);
            int b[7];
            decode(u.s, b);
            swap(b[u.p], b[u.p + 1]);
            int nts = encode(b);
            Push(nts, u.p, max(u.max_, u.p + 1), val); // 这里的max_很神啊
        }
    }
}
int a[7], b[7];
void solve(){
    int c[6] = {1, 2, 3, 4, 5, 6};
    int ans = inf;
    do
    {
        int all = 0, max_ = 0 ;
        rep(i, 6)
        {
            int fro = a[c[i] - 1];
            int to_ = b[i];
            if(fro != to_) max_ = max(max_, c[i] - 1 );
            all += abs(fro - to_);
        }
        int exc = inf;
        for(int i = max_ ; i< 6 ; i++)
            exc = min(exc, VIS[encode(c)][i]);
        all += exc;
//        if(encode(c) == 612345 ){
//              cout<<all <<" "<< exc<<" "<< max_ << endl;
//        }
        ans = min(ans,all);
    }
    while(next_permutation(c, c + 6));
    printf("%d\n",ans);
}
char s[100];
void read(int* a){
    scanf("%s",s);
    rep(i, 6){
        a[i] = s[i] - '0';
    }
}
int main()
{
    init_bfs();
    int T;
    scanf("%d",&T);
    while(T--){
        read(a);
        read(b);
        solve();
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值