题解 P2578 【[ZJOI2005]九数码游戏】

· · 题解

竟然没有C++的题解么

来一个C++的题解...

这道题……感觉&细节各种错

首先这个输出状态很麻烦...

从初始状态到末状态是一棵树

从根节点搜子叶要递归很麻烦

所以解决方案有两种

将输入状态定位末状态,初状态为

0 1 2 3 4 5 6 7 8 倒着搜

然后类似

while(!c)
{
    cout<<list[c]; 
    c=list[c];
}

当然我们定义为 node list[1000000];输出数组, 好像是个链表吧...(还是一棵树,,还是啥链表树,,傻傻分不清啊)

定义个print函数.

然后,,当然,,q.tail的父节点当然是q.head啦

但是STL的queue好像不支持酱紫呀

于是干脆手写队列

和STL用法完全一样

特别注意的就是数组一定要开得贼大

不然无输出,,鬼知道特么要1000000呀

我开的1000,只有40分呢,郁闷了半天

输出当然我是用链表了呀

如果会用指针写链表最好,,节约空间和时间

大概是这么写吧..忘了,一年没用过了

Type*list=new list; 
//动态链表建立
Type temp=list;
list=new Type;
list->father=temp;
scanf(list.data)
//遍历
while(list!=NULL)
{
    print(list->data);
    list=list->father;
}

哎呀……废话半天了,,其实我也不会 下面才是重点

#include<iostream>
#include<cstring>
template<typename T_queue>                                           //模板类, 
class queue                                                           //可以访问下标的队列 
{

public:

    queue(){head=1;tail=0;std::memset(data,0,sizeof(data));}
    void push(T_queue a){data[++tail]=a;}
    void pop(){if(head<=tail)head++;}
    T_queue front(){return data[head];}
    T_queue back(){return data[tail];}
    bool empty(){return head>tail;}
    T_queue data[2000000];
    int tail,head;
    int father;
};
template<typename T_stack>
class stack                                                     //栈 
{

public:

    stack(){std::memset(data,0,sizeof(data));tail=0;}
    void push(T_stack a){data[++tail]=a;}
    void pop(){if(tail>0)tail--;}
    bool empty(){return tail==0;};
    T_stack top(){return data[tail];}

private:

    T_stack data[2000000];
    int tail;
};
class node                //当前状态最小步数,当前状态. 
{

public:

    int a[10],step;
}s;
///////////////////////// 
int temp_stack_list[2000000];                                           //temp_Type前缀代表Type变量预处理用的临时变量 
int f[]={1,1,2,6,24,120,720,5040,40320,326880},book[1000000];  //阶乘打表 
queue<node>q;
stack<int*>list;  //用法和STL完全一样,,除了下标访问 
//////////////////////////以上定义全局变量 
using namespace std;
void next(int*a,int i)                         //两种状态变化方式 
{                                             
    if(i==1)
    {
        int temp_a0=a[0];
        a[0]=a[3];a[3]=a[6];a[6]=a[7];a[7]=a[8];a[8]=a[5];a[5]=a[2];a[2]=a[1];
        a[1]=temp_a0;
        return;
    }
    if(i==2)
    {
        int temp_a5=a[5];
        a[5]=a[4];a[4]=a[3];
        a[3]=temp_a5;
        return;
    }
}
int inline cantor_expansion(int*a)             //康拓展开 ,,特殊的hash函数 
{
    int ans=0;
    for(int i=0;i<9;i++)
    {
        int tmp=0;                   
        for(int j=i+1;j<9;j++)
            if(a[i]>a[j])tmp++;
        ans+=tmp*f[8-i];
    }
    return ans;
}
void print(int*a)                              //打印数组 
{
    for(int i=0;i<9;i++)
    {
        cout<<a[i]<<" ";
        if((i+1)%3==0)
            cout<<endl;    
    }
}
int main()
{
    int end=0;
    for(int i=0;i<9;i++)cin>>s.a[i];
    if(cantor_expansion(s.a)==0)
    {
        cout<<0;
        return 0;
    }
    q.push(s);
    book[cantor_expansion(s.a)]=1;
    while(!q.empty())                       //裸的广度优先搜索也能过,,其他的懒得写,,嫌代码不够长么 
    {
        for(int i=2;i>0;--i)
        {
            node now_status=q.front();
            next(now_status.a,i);
            now_status.step=q.front().step+1;
            if(cantor_expansion(now_status.a)==end)
            {
                cout<<now_status.step<<endl;
                q.push(now_status);
                temp_stack_list[q.tail]=q.head;
                int p=q.tail;
                do
                {
                    list.push(q.data[p].a);             //入栈,,把输出顺序颠倒下 
                    p=temp_stack_list[p];
                }
                while(p);
                cout<<endl;
                print(list.top());
                list.pop();
                while(!list.empty())
                {
                    cout<<endl<<endl;
                    print(list.top());                 //输出 
                    list.pop();
                }                
                return 0;
            }
            if(book[cantor_expansion(now_status.a)]==0)
            {
                book[cantor_expansion(now_status.a)]=1;
                q.push(now_status);
                temp_stack_list[q.tail]=q.head;                     //伪链表 
            }        
        }
        q.pop();
    }
    cout<<"UNSOLVABLE"; 
}