zoukankan      html  css  js  c++  java
  • [ZJOI2005]九数码游戏

    [ZJOI2005]九数码游戏

    题目描述

    输入输出格式

    输入格式:

    输入文件中包含三行三列九个数,同行的相邻两数用空格隔开,表示初始状态每个方格上的数字。初始状态不会是目标状态。

    输出格式:

    如果目标状态无法达到,则输出“UNSOLVABLE”(引号不输出)。

    否则,第一行是一个整数S,表示最少的操作次数。接下来4 × (S + 1)行,每四行表示一个状态:前三行每行三个整数,相邻两数用空格隔开,表示每个方格上的数字,第四行是一个空行,作为分隔。第一个状态必须是初始状态,最后一个状态必须是目标状态。

    输入输出样例

    输入样例#1:
    2 3 0
    1 8 7
    5 4 6
    
    输出样例#1:
    4
    2 3 0
    1 8 7
    5 4 6
    
    1 2 3
    5 8 0
    4 6 7
    
    1 2 3
    0 5 8
    4 6 7
    
    0 1 2
    4 5 3
    6 7 8
    
    0 1 2
    3 4 5
    6 7 8

    因为这是3*3的全排列矩阵变换;
    最多有9!(362880)种状态;
    用BFS,搜到终点为止,中间记录一下路径;
    将3*3的全排列映射成一一对应的数,可以用康托展开;
    最好不要用map,可能会超时;

    #include<iostream>  
    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    #include<map>  
    using namespace std;  
    
    int a[9],q[400008],st,ed,b[9],f[9],ge,ans;
    int c[400008],hash[400008];
    int  fac[10]={1,1,2,6,24,120,720,5040,40320}; 
    
    int calc1()  
    {  
        int i,j,t,sum;  
        sum=0;  
        for(i=0;i<9;i++)  
        {  
            t=0;  
            for(j=i+1;j<9;j++)  
                if(a[i]>a[j])  
                    ++t;  
            sum+=t*fac[9-i-1];  
        }  
        return sum+1;  
    }  
    
    int calc()  
    {  
        int i,j,t,sum;  
        sum=0;  
        for(i=0;i<9;i++)  
        {  
            t=0;  
            for(j=i+1;j<9;j++)  
                if(b[i]>b[j])  
                    ++t;  
            sum+=t*fac[9-i-1];  
        }  
        return sum+1;  
    }  
    
    void fen(int x)  
    {   
        int i,j,t,vst[9]={0};
        x--; 
        for(i=0;i<9;i++)  
        {  
            t=x/fac[9-i-1];  
            for(j=0;j<9;j++)  
                if(!vst[j])  
                {
                    if(t==0) break;  
                    --t;  
                }
            b[i]=j;
            vst[j]=1;
            x%=fac[9-i-1];
        }  
    }  
    
    int main()  
    {  
        int x=0;
        for(int i=1;i<=3;i++)
            for(int j=1;j<=3;j++){
                scanf("%d",&a[(i-1)*3+j-1]);
            }
        x=calc1();
        ge=1;
        if(x==ge){
            printf("0");
            return 0;
        }
        q[1]=x;
        hash[x]=-1;
        st=0; ed=1;
        while(st<ed){
            int x=q[++st];
            fen(x);
            for(int i=0;i<9;i++)
                f[i]=b[i];
            b[3]=f[5];
            b[4]=f[3];
            b[5]=f[4];
            int y=calc();
            if(hash[y]==0){
                hash[y]=x;
                ed++;
                q[ed]=y;
            }
            if(y==ge)
                break;
            b[3]=f[3];
            b[4]=f[4];
            b[5]=f[5];
            
            b[0]=f[3];
            b[1]=f[0];
            b[2]=f[1];
            b[5]=f[2];
            b[8]=f[5];
            b[7]=f[8];
            b[6]=f[7];
            b[3]=f[6];
            
            y=calc();
            if(hash[y]==0){
                hash[y]=x;
                ed++;
                q[ed]=y;
            }
            if(y==ge)
                break;
        }
        x=hash[ge];
        if(x==0){
            printf("UNSOLVABLE
    ");
            return 0;
        }
        while(x!=-1){
            ans++;
            c[ans]=x;
            x=hash[x];
        }
        printf("%d
    ",ans);
        for(int i=ans;i>0;i--){
            fen(c[i]);
            printf("%d %d %d
    ",b[0],b[1],b[2]);
            printf("%d %d %d
    ",b[3],b[4],b[5]);
            printf("%d %d %d
    ",b[6],b[7],b[8]);
            printf("
    ");
        }
        if(ans>=1){
            printf("0 1 2
    ");
            printf("3 4 5
    ");
            printf("6 7 8
    ");
        }
    }



  • 相关阅读:
    LUA学习
    python中的面向对象学习以及类的多态
    python中的面向对象学习之继承实例讲解
    python中的面向对象学习以及类的继承和继承顺序
    python中的面向对象学习以及类的封装(这篇文章初学者一定要好好看)
    python中的re模块
    python中configparser模块的使用
    python中装饰器
    python中简单的递归(断点报错的小福利)
    python中函数与函数式编程(二)
  • 原文地址:https://www.cnblogs.com/WQHui/p/7677338.html
Copyright © 2011-2022 走看看