nswoj 2327 MX的密码锁


点击打开链接



这题一看就是简单搜索,,,可是现场没过去,超时。  因为我用了康托展开。


然后队友都觉得自己有题能写,然后我就没写。


后来学弟过了,,直接存就好。。

后来我的代码没问题!!!!!!!.怪我zz了。。。


#include <stdio.h>
#include <iostream>
#include <queue>
#include <bits/stdc++.h>
#include <string.h>
using namespace std;
int v[377777];
int f[11];
struct node{
    int ma[3][3];
    int hash_val;
    int step;
}e,u,s,ed;


int get_hash(node a){
    int ret=0,num=8;
    for(int i=0;i<3;++i){
        for(int j=0;j<3;++j){
            int x=0;
            for(int l=j+1;l<3;++l)
                if(a.ma[i][j]>a.ma[i][l]) x++;
            for(int k=i+1;k<3;++k)
                for(int l=0;l<3;l++)
                    if(a.ma[i][j]>a.ma[k][l]) x++;
            ret+=f[num]*x;num--;
        }
    }
    return ret;
}


int bfs(){
    if(s.hash_val==ed.hash_val) return s.step;
    queue<node> que;
    while(!que.empty())que.pop();
    v[s.hash_val]=1;
    que.push(s);
    while(~que.empty()){
        e=que.front();
        if(e.step>=5) return -1;
        if(e.hash_val==ed.hash_val) return e.step;
        que.pop();
        for(int i=0;i<3;++i){
            u=e;
            int t=u.ma[i][0];
            u.ma[i][0]=u.ma[i][1];
            u.ma[i][1]=u.ma[i][2];
            u.ma[i][2]=t;
            u.hash_val=get_hash(u);if(u.hash_val==ed.hash_val) return e.step+1;
            if(!v[u.hash_val]&&u.step<=5) {
                u.step++;
                que.push(u);
            }
            u=e;
            t=u.ma[i][0];
            u.ma[i][0]=u.ma[i][2];
            u.ma[i][2]=u.ma[i][1];
            u.ma[i][1]=t;
            u.hash_val=get_hash(u);if(u.hash_val==ed.hash_val) return e.step+1;
            if(!v[u.hash_val]&&u.step<=5){
                u.step++;que.push(u);
            }
            u=e;
            t=u.ma[0][i];
            u.ma[0][i]=u.ma[1][i];
            u.ma[1][i]=u.ma[2][i];
            u.ma[2][i]=t;
            u.hash_val=get_hash(u);if(u.hash_val==ed.hash_val) return e.step+1;
            if(!v[u.hash_val]&&u.step<=5){
                u.step++;que.push(u);
            }
            u=e;
            t=u.ma[0][i];
            u.ma[0][i]=u.ma[2][i];
            u.ma[2][i]=u.ma[1][i];
            u.ma[1][i]=t;
            u.hash_val=get_hash(u);if(u.hash_val==ed.hash_val) return e.step+1;
            if(!v[u.hash_val]&&u.step<=5){
                u.step++;que.push(u);
            }
        }
    }
}
int main(){
    int T;
    f[0]=1;
    for(int i=1;i<10;++i) f[i]=f[i-1]*i;
    for(int i=0;i<3;++i)for(int j=0;j<3;++j) ed.ma[i][j]=i*3+j+1;
    ed.hash_val=get_hash(ed);
    scanf("%d",&T);
    while(T--){
        memset(v,0,sizeof(v));
        for(int i=0;i<3;++i)
            for(int j=0;j<3;++j)
                scanf("%1d",&s.ma[i][j]);
        s.hash_val=get_hash(s);
        s.step=0;
        int ans=bfs();
        if(ans==-1) printf("impossible\n");
        else printf("%d\n",ans);
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值