码迷,mamicode.com
首页 > 其他好文 > 详细

ACM-双向BFS之魔板——求助ING!

时间:2014-05-01 17:38:02      阅读:315      评论:0      收藏:0      [点我收藏+]

标签:acm   双向bfs   魔板   求助ing   help   

魔板

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 1675    Accepted Submission(s): 353

Problem Description
在魔方风靡全球之后不久,Rubik先生发明了它的简化版——魔板。魔板由8个同样大小的方块组成,每个方块颜色均不相同,可用数字1-8分别表示。任一时刻魔板的状态可用方块的颜色序列表示:从魔板的左上角开始,按顺时针方向依次写下各方块的颜色代号,所得到的数字序列即可表示此时魔板的状态。例如,序列(1,2,3,4,5,6,7,8)表示魔板状态为:

1 2 3 4
8 7 6 5

对于魔板,可施加三种不同的操作,具体操作方法如下:

A: 上下两行互换,如上图可变换为状态87654321
B: 每行同时循环右移一格,如上图可变换为41236785
C: 中间4个方块顺时针旋转一格,如上图可变换为17245368

给你魔板的初始状态与目标状态,请给出由初态到目态变换数最少的变换步骤,若有多种变换方案则取字典序最小的那种。
 
Input
每组测试数据包括两行,分别代表魔板的初态与目态。
 
Output
对每组测试数据输出满足题意的变换步骤。
 
Sample Input
12345678 17245368 12345678 82754631
 
Sample Output
C AC
 

这道题,BFS会超时,于是我用的双向BFS。。。
这题目中的VIS要用到 康托展开(详情可戳  http://blog.csdn.net/lttree/article/details/24798653 )

我的思路:
因为字典序,所以按照A->B->C搜索。
q队列存正向搜索的,搜索过的置1,p队列存反向搜索的,搜索过的置2。(初始化为0)
每次都扩展一层结点。
输出的时候先输出 正向的答案  再反向 输出反向的答案。
VIS数组内存到达该点时的节点和标记(1或者2)

网上说用预处理来做,
但是我试了试发现双广不会超时,就是WA。。。快被虐呆了~~o(>_<)o ~~
求大神大牛们帮忙看一下。。。
bubuko.com,布布扣


#include <iostream>
#include <string.h>
#include <queue>
using namespace std;
struct Node
{
    char board[8],key[101];
    int step;
    bool operator <( const Node n )const
    {
        return step<n.step;
    }
};
struct VIS
{
    int flag;
    Node k;
}vis[40320+1];
int  fac[] = {1,1,2,6,24,120,720,5040,40320};
char ini[8],ans[8];
// 康托展开
int kangtuo(char a[])
{
    int i,j,t,sum;
    sum=0;
    for( i=0; i<8 ;++i)
    {
        t=0;
        for(j=i+1;j<8;++j)
            if( a[i]>a[j] )
                ++t;
        sum+=t*fac[8-i-1];
    }
    return sum+1;
}
// 输出函数
void print( Node n,Node m )
{
    int i;
    for(i=0;i<n.step;++i)
        cout<<n.key[i];
    for(i=m.step-1;i>=0;--i)
        cout<<m.key[i];
    cout<<endl;
}
void bfs( void )
{
    memset(vis,0,sizeof(vis));
    priority_queue <Node> q;
    priority_queue <Node> p;
    Node pre,lst;
    int i,sp=0;

    // 初始化
    for(i=0;i<8;++i)
        pre.board[i]=ini[i];
    pre.step=0;
    vis[kangtuo(pre.board)].flag=1;
    vis[kangtuo(pre.board)].k=pre;
    q.push(pre);

    for(i=0;i<8;++i)
        pre.board[i]=ans[i];
    pre.step=0;
    vis[kangtuo(pre.board)].flag=2;
    vis[kangtuo(pre.board)].k=pre;
    p.push(pre);

    // 双向BFS
    while( !q.empty() && !p.empty() )
    {
        // 将每一层都扩展
        while( q.top().step==sp )
        {
            pre=q.top();
            q.pop();

            // 按A方案变化
            lst=pre;
            for(i=0; i<8; ++i)
                lst.board[i]=pre.board[7-i];
            lst.key[lst.step++]=‘A‘;
            if( vis[kangtuo(lst.board)].flag==2 )
            {
                print(lst,vis[kangtuo(lst.board)].k);
                return;
            }
            if( !vis[kangtuo(lst.board)].flag )
            {
                vis[kangtuo(lst.board)].flag=1;
                vis[kangtuo(lst.board)].k=lst;
                q.push(lst);
            }

            // 按B方案变化
            lst=pre;
            for(i=0; i<8; ++i)
            {
                if(i==0)    lst.board[i]=pre.board[3];
                else if(i==7)   lst.board[i]=pre.board[4];
                else    lst.board[i]=pre.board[i-1];
            }
            lst.key[lst.step++]=‘B‘;
            if( vis[kangtuo(lst.board)].flag==2 )
            {
                print(lst,vis[kangtuo(lst.board)].k);
                return;
            }
            if( !vis[kangtuo(lst.board)].flag )
            {

                vis[kangtuo(lst.board)].flag=1;
                vis[kangtuo(lst.board)].k=lst;
                q.push(lst);
            }

            // 按C方案变化
            lst=pre;
            lst.board[1]=pre.board[6];
            lst.board[2]=pre.board[1];
            lst.board[5]=pre.board[2];
            lst.board[6]=pre.board[5];
            lst.key[lst.step++]=‘C‘;
            if( vis[kangtuo(lst.board)].flag==2 )
            {
                print(lst,vis[kangtuo(lst.board)].k);
                return;
            }
            if( !vis[kangtuo(lst.board)].flag )
            {
                vis[kangtuo(lst.board)].flag=1;
                vis[kangtuo(lst.board)].k=lst;
                q.push(lst);
            }
        }
        while( p.top().step==sp )
        {
            pre=p.top();
            p.pop();

            //A
            lst=pre;
            for(i=0; i<8; ++i)
                lst.board[i]=pre.board[7-i];

            if( vis[kangtuo(lst.board)].flag==1 )
            {
                print(vis[kangtuo(lst.board)].k,lst);
                return;
            }
            if( !vis[kangtuo(lst.board)].flag )
            {
                lst.key[lst.step++]=‘A‘;
                vis[kangtuo(lst.board)].flag=2;
                vis[kangtuo(lst.board)].k=lst;
                p.push(lst);
            }
            //B
            lst=pre;
            for(i=0; i<8; ++i)
            {
                if(i==0)    lst.board[i]=pre.board[3];
                else if(i==7)   lst.board[i]=pre.board[4];
                else    lst.board[i]=pre.board[i-1];
            }

            if( vis[kangtuo(lst.board)].flag==1 )
            {
                print(vis[kangtuo(lst.board)].k,lst);
                return;
            }
            if( !vis[kangtuo(lst.board)].flag )
            {
                lst.key[lst.step++]=‘B‘;
                vis[kangtuo(lst.board)].flag=2;
                vis[kangtuo(lst.board)].k=lst;
                p.push(lst);
            }
            //C
            lst=pre;
            lst.board[1]=pre.board[6];
            lst.board[2]=pre.board[1];
            lst.board[5]=pre.board[2];
            lst.board[6]=pre.board[5];

            if( vis[kangtuo(lst.board)].flag==1 )
            {
                print(vis[kangtuo(lst.board)].k,lst);
                return;
            }
            if( !vis[kangtuo(lst.board)].flag )
            {
                lst.key[lst.step++]=‘C‘;
                vis[kangtuo(lst.board)].flag=2;
                vis[kangtuo(lst.board)].k=lst;
                p.push(lst);
            }
        }
        ++sp;
    }
}
int main()
{
    while( cin.getline(ini,10,‘\n‘) )
    {
        cin.getline(ans,10,‘\n‘);
        bfs();
    }
    return 0;
}




ACM-双向BFS之魔板——求助ING!,布布扣,bubuko.com

ACM-双向BFS之魔板——求助ING!

标签:acm   双向bfs   魔板   求助ing   help   

原文地址:http://blog.csdn.net/lttree/article/details/24811373

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!